2017-03-14 2 views
4

J'ai écrit une fonction qui convertit le texte HTML en NSAttributedString. Cela fonctionne bien. Cependant, j'ai remarqué que certaines balises lorsqu'elles sont imbriquées dans une autre balise, leurs polices sont écrasées.Objectif c - HTML to NSAttributedString

Voici mon code.

+(NSMutableAttributedString*) replaceHTMLTags : (NSString*) text : (NSString*) fontName : (CGFloat) fontSize 
{ 
    UIFont* font = [UIFont fontWithName:fontName size:fontSize]; 
    NSMutableParagraphStyle* paragraphStyle = [[NSMutableParagraphStyle alloc]init]; 
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; 
    paragraphStyle.alignment = NSTextAlignmentJustified; 

    text = [text stringByReplacingOccurrencesOfString:@"<br>" withString:@"\n"]; 
    NSMutableAttributedString* finalText = [[NSMutableAttributedString alloc]initWithString:text]; 

    [finalText setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, [finalText string].length)]; 

    finalText = [self recurseFunc:finalText :@"" : font : paragraphStyle]; 
    return finalText; 
} 

+(NSMutableAttributedString*) recurseFunc : (NSMutableAttributedString*) text : (NSString*) tag : (UIFont*) font : (NSMutableParagraphStyle*) paragraphStyle 
{ 
    NSMutableAttributedString* finalText = text; 

    NSRange newOpenTagRange; 
    //RECURSE IF THERE ARE MORE TAGS 
    while((newOpenTagRange = [[text string] rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound) 
    { 
     NSString* openTagName = [[text string] substringWithRange:newOpenTagRange]; 
     NSString* closeTagName = [self getCloseTagName: openTagName]; 
     NSRange newCloseTagRange = [[text string ]rangeOfString:closeTagName]; 

     if(newCloseTagRange.location != NSNotFound) 
     { 
      NSString* textWithTags = [[text string] substringWithRange:NSMakeRange(newOpenTagRange.location, newCloseTagRange.location - newOpenTagRange.location + newCloseTagRange.length)]; 
      NSString* newPlainText = [textWithTags stringByReplacingOccurrencesOfString:openTagName withString:@""]; 
      newPlainText = [newPlainText stringByReplacingOccurrencesOfString:closeTagName withString:@""]; 

      NSMutableAttributedString* newText = [[NSMutableAttributedString alloc]initWithString:newPlainText attributes:@{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle}]; 

      newText = [self recurseFunc:newText :openTagName : font : paragraphStyle]; 
      [finalText replaceCharactersInRange:NSMakeRange(newOpenTagRange.location, newCloseTagRange.location - newOpenTagRange.location + newCloseTagRange.length) withAttributedString:newText]; 
     } 
     else 
     { 
      NSLog(@"Cannot find closing tag for tag %@", openTagName); 
     } 
    } 

    //FORMAT HTML TAGS 
    if([tag containsString:@"<p"]) 
    { 
     [finalText.mutableString appendString:@"\n\n"]; 
    } 

    else if ([tag isEqualToString:@"<i>"]) 
    { 
     UIFont* italicFont = [UIFont fontWithName:@"Arial-ItalicMT" size:DEFAULT_FONT_SIZE]; 
     [finalText addAttribute:NSFontAttributeName value:italicFont range:NSMakeRange(0, [finalText string].length)]; 
    } 
    else if ([tag isEqualToString:@"<b>"]) 
    { 
     UIFont* boldFont = [UIFont fontWithName:@"Arial-BoldMT" size:DEFAULT_FONT_SIZE]; 
     [finalText addAttribute:NSFontAttributeName value:boldFont range:NSMakeRange(0, [finalText string].length)]; 

    } 
    else if([tag isEqualToString:@"<ul>"]) 
    { 
     NSMutableParagraphStyle* tempStyle = [[NSMutableParagraphStyle alloc]init]; 
     tempStyle.headIndent = 30; 
     tempStyle.firstLineHeadIndent = 10; 
     tempStyle.lineBreakMode = NSLineBreakByWordWrapping; 
     tempStyle.alignment = NSTextAlignmentJustified; 

     NSString* temp = [[finalText string]stringByReplacingOccurrencesOfString:@"###" withString:@"•\t"]; 
     temp = [NSString stringWithFormat:@"\n%@", temp]; 
     [finalText setAttributedString:[[NSAttributedString alloc] initWithString:temp]]; 

     [finalText addAttribute:NSParagraphStyleAttributeName value:tempStyle range:NSMakeRange(0, [finalText string].length)]; 


    } 
    else if ([tag isEqualToString:@"<li>"]) 
    { 
     NSMutableAttributedString* tempAS = [[NSMutableAttributedString alloc]initWithString:@"###$$$\n"]; 
     NSRange r = [[tempAS string]rangeOfString:@"$$$"]; 
     [tempAS replaceCharactersInRange:r withAttributedString:finalText]; 
     [finalText setAttributedString:tempAS]; 

    } 
    return finalText; 
} 

Ceci fait exactement ce qu'il est censé faire, sauf pour un cas spécifique.

Par exemple, si j'ai un <b> ou une balise <i> dans une balise <ul><li>, le <b> ou <i> ne pas obtenir rendus.

+0

N'a pas testé votre code entier, mais avec un QuickLook, je suppose que ' someText' a gagné » t travail, ne donnant pas italique et gras. – Larme

+0

@Larme J'ai testé tout le code. Tout fonctionne bien. Le problème est dans un scénario comme celui-ci. '

  • Certains Texte
'. Où "Texte" ne devient pas gras. Cependant, si c'est juste '

Certains Texte

' ça marche très bien. – user2771150

+1

Remplacer 'NSString * temp = [[chaîne_final]] stringByReplacingOccurrencesOfString: @" ### "withString: @" • \ t "]; temp = [NSString stringWithFormat: @ "\ n% @", temp]; [finalText setAttributedString: [[NSAttributedString alloc] initWithString: temp]]; 'avec' [finalText replaceCharactersInRange: [[chaîne_final]] rangeOfString: @ "###"] withString: @ "• \ t"]; 'et cela devrait être résoudre une partie de votre problème. – Larme

Répondre

2

Pour convertir HTML à NSAttributedString vous pouvez utiliser le code suivant:

[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] 
          options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, 
             NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} 
        documentAttributes:nil error:nil];