iOS支持富文本Label控件

来源:互联网 发布:咫尺网络微官网 编辑:程序博客网 时间:2024/06/06 00:52

写在前面

都说需求才是技术的最好驱动力,一点也没有错~

  1. 由于在业务开发的过程中经常碰到一些文案需要高亮显示或者是加粗等需求;
  2. android 的TextView源生控件是自动支持的,但是对于iOS却没有,所以非常有必要的写一个自定义控件对此功能进行支持;
  3. 以便于后续用到此功能,大大可以减少开发时间和重复代码。

直接上图,最直观:

首先来个简单一点的,只有一处高亮显示:

8月评论数同城<font color='#ff0000'>第134名</font>8月评论数,显示的如下


再复杂点,一处高亮且加粗:

8月评论数同城<font color='#ff0000'><b>第134名</b></font>8月评论数,显示的如下



来个更复杂点的,多处高亮且加粗:
8月<font color='#ff0000'><b>评论数</b></font>同城<font color='#ff0000'><b>第134名</b></font>8月评论数,显示的如下




解析富文本方法:
- (MTARichLabelTextMode *)flattenHTML:(NSString *)html trimWhiteSpace:(BOOL)trim{        NSScanner *theScanner = [NSScanner scannerWithString:html];    NSString *text = nil;    NSMutableArray<MTARichStyleMode *> *richArray = [NSMutableArray new];    MTARichLabelTextMode *richLabelMode = [MTARichLabelTextMode new];    NSArray<NSString*> *tarArray = [self targetStr:html];    while ([theScanner isAtEnd] == NO) {        MTARichStyleMode *stylemode = [MTARichStyleMode new];        // find start of tag        [theScanner scanUpToString:@"<" intoString:NULL] ;        // find end of tag        [theScanner scanUpToString:@"/" intoString:&text] ;                if([text containsString:@"color"]){            stylemode.color = [self tarStrHTML:text reg:@"['](.*)[']" repStr:@"'"];        }        if([text containsString:@"<b"]){            stylemode.bold = YES;        }        text = nil;        if(stylemode.color.length>0||stylemode.bold){            [richArray addObject:stylemode];        }    }        for (NSUInteger i =0; i< tarArray.count; i++) {        richArray[i].target = tarArray[i];    }    richLabelMode.desc = [self getDesc:html];    richLabelMode.styleArray = richArray;    return  richLabelMode;}//获取富文本的目标文字- (NSArray<NSString*> *)targetStr:(NSString *)html{    NSScanner *theScanner = [NSScanner scannerWithString:html];    NSString *text = nil;    NSMutableArray<NSString *> *tarArray = [NSMutableArray new];    while ([theScanner isAtEnd] == NO) {        // find start of tag        [theScanner scanUpToString:@">" intoString:NULL] ;        // find end of tag                [theScanner scanUpToString:@"/" intoString:&text] ;        // replace the found tag with a space        //(you can filter multi-spaces out later if you wish)        if([text containsString:@">"] && [text containsString:@"<"]){            text = [self getSynax:text];                    if(text!=nil){                text = [text stringByReplacingOccurrencesOfString:@">"                                                       withString:@""];                if(text.length>0)                    [tarArray addObject:text];            }        }        text = nil;            }        return  tarArray;}//去掉多余标签- (NSString *)getSynax:(NSString *) html{    NSScanner *theScanner = [NSScanner scannerWithString:html];    NSString *text = nil;    while ([theScanner isAtEnd] == NO) {        // find start of tag        [theScanner scanUpToString:@">" intoString:NULL] ;        // find end of tag        [theScanner scanUpToString:@"<" intoString:&text] ;        if(text!=nil){            text = [text stringByReplacingOccurrencesOfString:@">"                                                   withString:@""];        }    }        return text;}//过滤掉富文本标签返回一个纯文本- (NSString *)getDesc:(NSString *) html{    NSScanner *theScanner = [NSScanner scannerWithString:html];    NSString *text = nil;    while ([theScanner isAtEnd] == NO) {        // find start of tag        [theScanner scanUpToString:@"<" intoString:NULL] ;        // find end of tag        [theScanner scanUpToString:@">" intoString:&text] ;        html = [html stringByReplacingOccurrencesOfString:                [ NSString stringWithFormat:@"%@>", text]                                               withString:@""];    }        return [html stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];}- (NSString *)tarStrHTML:(NSString *)html reg:(NSString *)regStr repStr:(NSString*) rpStr{    NSString *result = nil;    NSRange range = [html rangeOfString:regStr options:NSRegularExpressionSearch];    if (range.location != NSNotFound) {        NSLog(@"%@", [html substringWithRange:range]);        result = [html substringWithRange:range];        result = [result stringByReplacingOccurrencesOfString:rpStr withString:@""];    }    return result;}

设置到Label中:
- (void)setText:(NSString *)text {    if(text.length == 0) {        return;    }    MTARichLabelTextMode * secondAd = [self flattenHTML:text trimWhiteSpace:YES];    NSMutableParagraphStyle * paragraphStyle1 = [[NSMutableParagraphStyle alloc] init];    [paragraphStyle1 setLineSpacing:4];    NSMutableAttributedString *attributedStr02 = [[NSMutableAttributedString alloc] initWithString: secondAd.desc];        [attributedStr02 addAttribute:NSParagraphStyleAttributeName value:paragraphStyle1 range:NSMakeRange(0, [secondAd.desc length])];    //添加属性    //分段控制,最开始4个字符颜色设置成颜色    for(int i = 0;i<secondAd.styleArray.count;i++){        NSInteger targetLength02 = secondAd.styleArray[i].target.length;        if(secondAd.styleArray[i].color !=nil && targetLength02 >0){            [attributedStr02 addAttribute: NSForegroundColorAttributeName value: [UIColor nvColorWithHexString:secondAd.styleArray[i].color] range: [secondAd.desc rangeOfString:secondAd.styleArray[i].target]];        }        if(secondAd.styleArray[i].bold && targetLength02 >0){            [attributedStr02 addAttribute:NSStrokeWidthAttributeName value:@(-3) range:[secondAd.desc rangeOfString:secondAd.styleArray[i].target]];        }            }        self.attributedText = attributedStr02;    self.lineBreakMode = NSLineBreakByTruncatingTail;}


主体方法大致就是上面贴出来的,源码放在github上,看地址:点击打开链接


原创粉丝点击