前言
Feed流是大多数软件的标配,大多数都支持富文本、图片、视频,广告等。这个模块因为功能的增多变得越来越复杂,性能也变得越来越低,所以优化Feed流是必须的。 Feed的主要是图文显示、异步渲染。之前我们采用的是YYText的富文本支持,YYText在初期是能满足需求的,但YYText作者已经不维护了,还有YYText调用复杂和支持功能比较少,已经不能满足现在复杂的需求,为了解决之前留下的问题,参考网上开源库,就弄出了VVRichText.
之前的版本
做第一个版本的时候,既要快又要好的支持需求,选型YYKit和AsyncDisplayKit中纠结,因为AsyncDisplayKit侵入性和兼容性问题,最终采用了YYText框架支持富文本显示,还有YYWebImage框架很好支持Gif和Webp格式。但这个方式有几个问题:
- 采用这个这种方式就不得不把Feed被拆分成5个Cell。头像和文字成一个Cell,图片显示成一个Cell,时间显示和更多按钮一个Cell,点赞一个Cell,评论一个Cell,拆分的Cell过多,也造成渲染多次,维护麻烦。
- 引用YYWebImage的框架,不兼容之前的图片SDWebImage缓存库。又引入的YYCache和YYWebImage库。
- 数据和显示耦合紧密。
- 对点击、长按事件支持逻辑复杂。
- 计算一个Feed的高度复杂
优化的版本
解决之前的问题,网上没有答案,只能自己解决问题,这个VVRichText具备以下特性,解决了我所有的问题。
- 支持富文本显示,支持异步文本渲染。
- 可以在文本中插入本地图片,网络图片或UIView对象。
- 支持WebP、GIF等格式。
- 支持添加单击和长按事件到文本、图片。
- 绘制文本框架,绘制空心字,设置文本垂直对齐属性等。
- 解析文本中的表达式,如http(s)链接、@user、#theme#、电话号码。
- 快速设置图像角半径属性和模糊处理等。
- 支持布局控制多个图文元素
- 支持SDWebImage缓存库
例子
VVRichText,将页面元素抽象成文字和图片两个对象,自动布局多个对象,最终将所有对象最终渲染到一个View上。性能也是达到最优,在iPhone5手机上也 能如丝滑般的体验。
文字对象例子 TextWidget
- Feed正文内容模型
VVTextWidget *contentTextWidget = [VVTextWidget new];
contentTextWidget.maxNumberOfLines = 0;
contentTextWidget.text = statusModel.content;
contentTextWidget.font = [UIFont systemFontOfSize:15.0f];
contentTextWidget.textColor = VV_COLOR(40, 40, 40, 1);
contentTextWidget.frame = CGRectMake(nameTextWidget.left, nameTextWidget.bottom + 10.0f, VV_SCREEN_WIDTH - 80.0f, CGFLOAT_MAX);
// 添加长按复制
[contentTextWidget vv_addLongPressActionWithData:contentTextWidget.text
highLightColor:VV_COLOR(0, 0, 0, 0.25f)];
// 解析表情、主题、网址
[VVTextParser parseGeneralEmojiWithTextWidget:contentTextWidget];
[VVTextParser parseTopicWithVVTextWidget:contentTextWidget
linkColor:VV_COLOR(113, 129, 161, 1)
highlightColor:VV_COLOR(0, 0, 0, 0.15)];
[VVTextParser parseHttpURLWithTextWidget:contentTextWidget
linkColor:VV_COLOR(113, 129, 161, 1)
highlightColor:VV_COLOR(0, 0, 0, 0.15f)];
图片对象例子 ImageWidget
- Feed头像模型
VVImageWidget *avatarWidget = [[VVImageWidget alloc] initWithIdentifier:AVATAR_IDENTIFIER];
if (statusModel.avatar) {
avatarWidget.contents = statusModel.avatar;
} else {
avatarWidget.contents = [UIImage imageNamed:@"defaultavatar.png"];
}
avatarWidget.cornerRadius = 20.0f;
avatarWidget.cornerBackgroundColor = [UIColor whiteColor];
avatarWidget.backgroundColor = [UIColor whiteColor];
avatarWidget.frame = CGRectMake(10.0f, 20.0f, 40.0f, 40.0f);
avatarWidget.tag = 9;
avatarWidget.cornerBorderWidth = 1.0f;
avatarWidget.cornerBorderColor = [UIColor grayColor];
- 将图片和文字的Widget对象添加到VVWidgetCollect中
[self addWidget:nameTextWidget];
[self addWidget:contentTextWidget];
- Cell高度计算
self.height = [self suggestHeightWithBottomMargin:15.0f];
- 单独更新一个Cell异步线程渲染会闪烁,切换为主线程渲染,比如点击展开Feed正文
//展开Cell
- (void)openTableViewCell:(FeedCell *)cell {
NSInteger row = cell.indexPath.row;
[self.feedVM expendData:row];
[self reloadCell:row];
}
// 异步线程渲染会闪烁,切换为主线程渲染
- (void)reloadCell:(NSInteger)row {
self.asynDisplay = NO;
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:row inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
self.asynDisplay = YES;
}
- 更多的详情请访问 github.com/chinaxxren/…
集成
- 通过
pod 'VVRichText'集成到项目中