在很多 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
}
};
}