实现微信朋友圈动态列表
前言
项目中需要实现类似朋友圈动态的列表,需要用到图文混排,正好可以使用ibireme大神的开源控件YYText实现这种效果,在这里记录一下使用过程中遇到的问题,参考文章iOS 保持界面流畅的技巧。

布局
列表中的主要布局如下图所示,预先将每个cell的高度计算出来,并且将高度缓存下来,不重复计算高度。ibireme实现的微博列表Demo写的已经很清晰了,这里主要写下自己在使用时,遇到的一些问题。

1.TableView刷新时出现闪动问题
TableView在刷新的时候,YYLabel会出现闪动,解决方法是将异步绘制关闭displaysAsynchronously = NO;
,参考https://github.com/ibireme/YYKit/issues/64。
2.动态Label默认最多显示六行
计算文本的行数,YYTextContainer
有最大行数maximumNumberOfRows
属性,根据这个属性可以设置文本最大行数。
YYTextContainer *container = [YYTextContainer new];
container.size = CGSizeMake(kWBCellContentWidth, HUGE);
container.linePositionModifier = modifier;
//计算文本的行数,判断显示6行,还是显示完全
YYTextLayout *tmpTextLayout = [YYTextLayout layoutWithContainer:container text:text];
NSUInteger rowCount = tmpTextLayout.rowCount;
当行数大于6行时,显示展开按钮,点击展开按钮显示全部文本,显示收起按钮,将当前最大行数设置为6行。
//判断是否隐藏展开按钮
if (rowCount > 6) {
_isShowExpendButton = YES;
//判断展开或者收起状态
if (_isExpend == NO) {
container.maximumNumberOfRows = 6;
_expendButtonTitle = @"全文";
}else{
_expendButtonTitle = @"收起";
}
}else{
_isShowExpendButton = NO;
}
3.匹配字符串
将动态字符串中的[呵呵]
,[可爱]
等字符串替换为表情图片。将电话号码,网址等进行高亮显示,并且为其设置userInfo
,用于后面响应用户点击事件。将这些方法放在了NSString+Emotion
类中,方便调用。关于正则表达式怎么匹配,可以查看这篇文章从零开始学习正则表达式。
// 匹配 [表情]
NSArray<NSTextCheckingResult *> *emoticonResults = [[EmoticonHelper regexEmoticon] matchesInString:text.string options:kNilOptions range:text.yy_rangeOfAll];
NSUInteger emoClipLength = 0;
for (NSTextCheckingResult *emo in emoticonResults) {
if (emo.range.location == NSNotFound && emo.range.length <= 1) continue;
NSRange range = emo.range;
range.location -= emoClipLength;
if ([text yy_attribute:YYTextHighlightAttributeName atIndex:range.location]) continue;
if ([text yy_attribute:YYTextAttachmentAttributeName atIndex:range.location]) continue;
NSString *emoString = [text.string substringWithRange:range];
NSString *imagePath = [EmoticonHelper emoticonDic][emoString];
UIImage *image = [EmoticonHelper imageWithPath:imagePath];
if (!image) continue;
NSAttributedString *emoText = [NSAttributedString yy_attachmentStringWithEmojiImage:image fontSize:font.pointSize];
[text replaceCharactersInRange:range withAttributedString:emoText];
//emoText的length都是1
emoClipLength += range.length - 1;
}
响应手机号和网址的点击事件,获取高亮状态字符串的userInfo
,然后进行相应的操作。
/// 点击了 Label 的链接
- (void)cell:(TwitterCell *)cell didClickInLabel:(YYLabel *)label textRange:(NSRange)textRange{
NSAttributedString *text = label.textLayout.text;
if (textRange.location >= text.length) return;
YYTextHighlight *highlight = [text yy_attribute:YYTextHighlightAttributeName atIndex:textRange.location];
NSDictionary *info = highlight.userInfo;
if (info.count == 0) return;
if (info[kWBLinkURLName]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:info[kWBLinkURLName]]];
}else if (info[KWBLinkPhone]){
NSMutableString *str2=[[NSMutableString alloc] initWithFormat:@"tel:%@",info[KWBLinkPhone]];
UIWebView * callWebview = [[UIWebView alloc] init];
[callWebview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:str2]]];
[self.view addSubview:callWebview];
}
}
4.评论列表点击可以拷贝
评论视图是用UITableView
实现的,可以使用TableView的系统方法,实现长按cell,弹出copy
菜单,然后进行复制[UIPasteboard generalPasteboard].string = model.comment
。
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if (action == @selector(copy:)) {
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if (action == @selector(copy:)) {
TweetCommentModel *model;
if (self.commentArray.count > 0) {
model = self.commentArray[indexPath.row];
}
[UIPasteboard generalPasteboard].string = model.comment;
}
}
YYKit中微博Demo的表情键盘,自己也照着作者的代码敲了一篇,学到了很多。
