富文本点击事件-TTTAttributedLabel和YYtext的不同用法

在很多 TimeLine 的排版页面,都会用到富文本,多样式的文字展示,以及为某些特殊文字,比如@,# ,以及网址添加点击事件。这里就以为 @ 和 # 添加不同样式和点击事件 和 替换网址为某个特定图片,以及添加点击事件的功能,介绍一下主流应用的两个第三方库,TTTAttributedLabel 和 YYText 的一些用法。

TTTAttributedLabel
TTTAttributedLabel 继承于 UILabel,所以具有 UILabel 所有的属性和方法。通过CoreText绘制富文本。

1、初始化:

由于是继承与UILabel,因此和 UILabel 的初始化相同。

TTTAttributedLabel *label = [TTTAttributedLabel alloc] init];

2、赋值:
TTTAttributedLabel 是比较老的库,当时 UILabel 还并没有 attributedText 属性。通过 setText 进行赋值,在 block 里制定富文本规则。

NSString *message = @"@小明 #旅行计划# 网址是:http://blog.csdn.net/u013749108 完毕"
[label setText:message afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
    //label 整体  风格
    [mutableAttributedString addAttributes:[self textStyle] range:NSMakeRange(0, message.length)];

    //找出  # @ 
    NSArray *matches = [PXStatusUtil checkAllLinksWithOutUrlText:message];

    //遍历符合规则的结果
    for ( NSTextCheckingResult *match in matches ) {
        NSRange wordRange = [match range];
        //为符合结果的文字添加富文本属性字典 
        [mutableAttributedString addAttributes:[self linkStyle] range:wordRange];
    }

    //找出 url 添加文字样式
    NSArray *matches_with_url = [PXStatusUtil checkURLLinksWithText:data.message];
    for (NSUInteger i = matches_with_url.count; i > 0; i--) {
        NSTextCheckingResult *match = matches_with_url[i-1];
        NSRange urlRange = [match range];
        //为符合结果的文字添加富文本属性字典 
        [mutableAttributedString addAttributes:[self linkStyle] range:urlRange];
    }
    return mutableAttributedString;
}];

3、添加点击事件

// 为 # @ 添加点击事件
NSArray *matches = [PXStatusUtil checkAllLinksWithOutUrlText:message];
for ( NSTextCheckingResult *match in matches ) {
    //添加点击事件
    [label addLinkWithTextCheckingResult:match];
}
// 为 url 添加点击事件
NSArray *matches_with_url = [PXStatusUtil checkURLLinksWithText:message];
for (NSUInteger i = matches_with_url.count; i > 0; i--) {
    NSTextCheckingResult *match = matches_with_url[i-1];
    //添加点击事件
    [label addLinkWithTextCheckingResult:match];
}

4、点击事件回调
准守协议 TTTAttributedLabelDelegate ,设置 label的代理。然后实现协议方法:

- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithTextCheckingResult:(NSTextCheckingResult *)result{
    NSRange wordRange = [result range];
    NSString *link   = [label.text substringWithRange:wordRange];
    NSLog(@"%@",link);
    if ( [link hasPrefix:@"#"] ) {
         //Your Action
    }
    else if ( [link hasPrefix:@"@"] ) {
       //Your Action
    }
    else if ( [link hasPrefix:@"http"] || [link hasPrefix:@"https"]) {
       //Your Action
    }
}

TTTAttributedLabel 有一个很大的局限,不支持 NSTextAttachment ,因此无法在文本中插入图片,或者替换一段文字为图片。如果有这个需求,那么就可以考虑选择 YYText 了。


YYtext
YYtext 集成于 UIView ,但作者基本上移植了 UILabel 的所有属性。初始化方式也一样。

1、初始化:
如果需要设置 label 的多行显示,必须要设置 preferredMaxLayoutWidth 。

YYLabel *contentLabel = [[YYLabel alloc] init];
contentLabel.numberOfLines = 0;
contentLabel.preferredMaxLayoutWidth = ScreenWidth;

2、赋值

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:message attributes:[self textStyle]];

 // 获取 所有 url之外的 # 和 @
 NSArray *matches = [PXStatusUtil checkAllLinksWithOutUrlText:message];

 for (NSTextCheckingResult *match in matches_withOut_url){
        //YYText 好像无法一次添加整体属性字典,这里只能挨个添加某个属性
        [attributedString yy_setAttribute:NSForegroundColorAttributeName value:RGB(91, 160, 200) range:match.range];
        [attributedString yy_setAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleNone) range:match.range];

        //绑定点击事件
        YYTextHighlight *highlight = [YYTextHighlight new];
        NSRange attributeRange = match.range;
        NSString *topicString  = [message substringWithRange:attributeRange];

        //linkUrl 用来在点击事件回调里取出高亮的文字
        highlight.userInfo = @{@"linkUrl":topicString};
        [attributedString yy_setTextHighlight:highlight range:attributeRange];
 }


 // 获取 所有 url 替换成 我们想要的图片
 NSArray *matches_with_url = [PXStatusUtil checkURLLinksWithText:message];
 for (NSUInteger i = matches_with_url.count; i > 0; i--) {
        NSTextCheckingResult *match = matches_with_url[i-1];
        NSRange urlRange = [match range];

        UIImage *image = [UIImage imageNamed:@"ic_feed_link"];
        //创建图片的附件
        YYTextAttachment *attach = [YYTextAttachment attachmentWithContent:[UIImage imageNamed:@"ic_feed_link"]];
        attach.contentInsets = UIEdgeInsetsMake(-4, 0, 0, 0);
        //把图片附件转化为 attributedString
        NSMutableAttributedString *attachText = [NSMutableAttributedString yy_attachmentStringWithContent:image contentMode:UIViewContentModeCenter attachmentSize:image.size alignToFont:[UIFont systemFontOfSize:17] alignment:YYTextVerticalAlignmentBottom];

        NSString *linkUrlString = [message substringWithRange:urlRange];

        //把网址替换成 attachText
        [attributedString replaceCharactersInRange:urlRange withAttributedString:attachText];

        //取出网址 绑定点击事件 
        YYTextHighlight *highlight = [YYTextHighlight new];
        NSRange attributeRange  = NSMakeRange(urlRange.location, [attachText length]);
        highlight.userInfo = @{@"linkUrl":linkUrlString};
        [attributedString yy_setTextHighlight:highlight range:attributeRange];

 }

3、点击事件回调

- (void)addActionToContentLabel{
    @weakify(self)
    self.contentLabel.highlightTapAction = ^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
        @strongify(self)
         YYTextHighlight *highlight = [text yy_attribute:YYTextHighlightAttributeName atIndex:range.location];
        NSString *link = highlight.userInfo[@"linkUrl"];
        NSLog(@"%@",link);
        if ( [link hasPrefix:@"#"] ) {
           //Your Action
        }
        else if ( [link hasPrefix:@"@"] ) {
            //Your Action
        }
        else if ( [link hasPrefix:@"http"] || [link hasPrefix:@"https"]) {
            //Your Action
        }
    };
}

你可能感兴趣的:(iOS)