我已经编写了一个函数,可以将HTML文本转换为
以下是我的代码:
NSAttributedString
。它的运行良好。然而,我注意到当一些标签嵌套在另一个标签中时,它们的字体会被覆盖。以下是我的代码:
+(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;
}
这段代码完全按照预期工作,但有一个特定的情况需要注意。
例如,如果我在 <ul><li>
标签内部使用了 <b>
或 <i>
标签,那么这些标签将不会被呈现出来。
<b><i>someText</i></b>
不会起作用,无法同时加粗和倾斜。 - Larme<ul><li>Some<b>Text</b></li></ul>
。其中,“Text”没有变成粗体。然而,如果只是<p>Some <b>Text</b></p>
,它就可以正常工作。 - user2771150[finalText replaceCharactersInRange:[[finalText string] rangeOfString:@"###"] withString:@"•\t"];
替换NSString* temp = [[finalText string]stringByReplacingOccurrencesOfString:@"###" withString:@"•\t"]; temp = [NSString stringWithFormat:@"\n%@", temp]; [finalText setAttributedString:[[NSAttributedString alloc] initWithString:temp]];
这段代码,这样可以解决你的一个问题。 - LarmeNSMutableAttributedString* newText = [[NSMutableAttributedString alloc]initWithString:newPlainText attributes:@{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle}];
你正在覆盖字体,因此如果它是 “Arial-Bold”,则将被参数中的字体覆盖。 - Larme