直播問(wèn)題交流可加群 379258188
備注簡(jiǎn)書
此篇為重拾直播系列的第一篇逆害,基于之前的項(xiàng)目聊天室進(jìn)行了重構(gòu)和優(yōu)化碾盟!
優(yōu)化點(diǎn):1.使用自定義的融云消息類型 2.優(yōu)化聊天室cell高度計(jì)算方式
當(dāng)前項(xiàng)目效果展示:
此demo使用的是映客直播流括享,侵刪
直播間的消息使用的是融云直播聊天室方案愉粤,使用了自定義消息類型
- 文本消息(包括彈幕)
- 點(diǎn)贊消息
- 禮物消息
- 特效消息(進(jìn)場(chǎng)特效杀迹,全局禮物通知特效,GIF圖中為展示)
在這里先把消息類型略過(guò)劣针,在后面的文章中會(huì)介紹校镐,本次在介紹聊天室的實(shí)現(xiàn)
直播聊天室的要求:
- 富文本展示(等級(jí)+用戶姓名+禮物縮略圖)
- 文本消息 (看我的大白眼進(jìn)入了直播間,看我的大白眼關(guān)注了主播...)
- 不卡頓(滾動(dòng)流暢酿秸,高度計(jì)算準(zhǔn)確)
cell高度計(jì)算的思考
配合Masonry實(shí)現(xiàn)TableViewCell的高度自適應(yīng)灭翔,以及更易管理的高度緩存
這個(gè)文章的的方案思考比較深刻,再次我就不重復(fù)了辣苏!原本打算使用上述的方案中動(dòng)態(tài)高度四:緩存高度
,但是在使用過(guò)程了和設(shè)計(jì)需求有出入肝箱!不使用此方案還有一個(gè)重要原因,可以看我末尾補(bǔ)充稀蟋。
背后的灰色是根據(jù)文本長(zhǎng)度改變的
最終方案:
使用YYLabel
中的YYTextLayout
計(jì)算高度
YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(RCCRMsgW - 10.0f, MAXFLOAT)];
YYTextLayout *textLayout = [YYTextLayout layoutWithContainer:container text:self.messsageLabel.attributedText];
CGSize __labelSize = textLayout.textBoundingSize;
// 留出文本的上下間距增加15的高度
return __labelSize.height + 15;
RCDLiveTextMessageCell.h
@interface RCDLiveTextMessageCell : UITableViewCell
@property (nonatomic, strong) RCCRMessageModel *model;
- (CGFloat)heightForModel:(RCCRMessageModel *)message;
@end
RCDLiveTextMessageCell.m
@interface RCDLiveTextMessageCell()
/*!
顯示消息內(nèi)容的Label
*/
@property(nonatomic, strong) YYLabel *messsageLabel;
@property (nonatomic, strong) UIView *bgView;
@end
@implementation RCDLiveTextMessageCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:self.bgView];
[self.contentView addSubview:self.messsageLabel];
}
return self;
}
- (void)setModel:(RCCRMessageModel *)model {
_model = model;
// 進(jìn)行數(shù)據(jù)賦值
// 創(chuàng)建一個(gè)可變屬性字符串
NSMutableAttributedString *finalStr = [[NSMutableAttributedString alloc]init];
UIFont *font = [UIFont systemFontOfSize:15];
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineSpacing = 3;
UIImage *image = [UIImage imageNamed:@"dengji_1"]; // 測(cè)試數(shù)據(jù)
NSMutableAttributedString *attachText = [NSMutableAttributedString attachmentStringWithContent:image contentMode:UIViewContentModeCenter attachmentSize:image.size alignToFont:font alignment:YYTextVerticalAlignmentCenter];
[finalStr appendAttributedString:attachText];
[finalStr appendAttributedString:[[NSAttributedString alloc] initWithString:model.name attributes:@{NSFontAttributeName : font,NSForegroundColorAttributeName:[UIColor whiteColor]}]];
[finalStr appendAttributedString:[[NSAttributedString alloc] initWithString:model.message attributes:@{NSFontAttributeName : font,NSForegroundColorAttributeName:[UIColor yellowColor],NSParagraphStyleAttributeName:paragraphStyle}]];
[finalStr addAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, finalStr.length)];
self.messsageLabel.attributedText = finalStr;
// 很關(guān)鍵 寬度一定要準(zhǔn)確 (250 是tableview的寬度,-10是讓文本左右留出10的寬度)
YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(250 - 10.0f, MAXFLOAT)];
YYTextLayout *textLayout = [YYTextLayout layoutWithContainer:container text:self.messsageLabel.attributedText];
self.messsageLabel.textLayout = textLayout;
self.messsageLabel.frame = CGRectMake(4,4, textLayout.textBoundingSize.width, textLayout.textBoundingSize.height);
self.bgView.frame = CGRectMake(0, 0, self.messsageLabel.width + 8, self.messsageLabel.height + 6);
}
// 根絕數(shù)據(jù)計(jì)算cell的高度
- (CGFloat)heightForModel:(RCCRMessageModel *)message {
[self setModel:message];
// 很關(guān)鍵
YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(250 - 10.0f, MAXFLOAT)];
YYTextLayout *textLayout = [YYTextLayout layoutWithContainer:container text:self.messsageLabel.attributedText];
CGSize __labelSize = textLayout.textBoundingSize;
return __labelSize.height + 15;
}
#pragma mark - lazy
- (YYLabel *)messsageLabel {
if (_messsageLabel == nil) {
_messsageLabel = [[YYLabel alloc]init];
_messsageLabel.numberOfLines = 0;
_messsageLabel.textAlignment = NSTextAlignmentLeft;
_messsageLabel.lineBreakMode = NSLineBreakByCharWrapping;
_messsageLabel.displaysAsynchronously = YES;
_messsageLabel.textVerticalAlignment = YYTextVerticalAlignmentCenter;
}
return _messsageLabel;
}
- (UIView *)bgView {
if (_bgView == nil) {
_bgView = [[UIView alloc]init];
_bgView.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.25];
// 如果切原價(jià)卡頓的話,可以使用背景圖
_bgView.layer.cornerRadius = 4;
_bgView.layer.masksToBounds = YES;
}
return _bgView;
}
@end
高度計(jì)算
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
RCCRMessageModel *model = [self.conversationDataRepository objectAtIndex:indexPath.row];
if (model.cellHeight == 0) {
CGFloat cellHeight = [self.tempMsgCell heightForModel:model];
model.cellHeight = cellHeight;
return cellHeight;
}else{
return model.cellHeight;
}
}
本文demo https://github.com/TsuiOS/HsuLive
補(bǔ)充
如果實(shí)現(xiàn)映客等主流平臺(tái)聊天區(qū)域頂部漸隱消失效果
iOS 仿花椒直播聊天室消息列表漸隱消失效果
實(shí)際解決方案:
要為聊天區(qū)域新建一個(gè)containerView
,給containerView
設(shè)置頂部漸變效果為什么不使用參考的方案四
// 根絕數(shù)據(jù)計(jì)算cell的高度
- (CGFloat)heightForModel:(CellModel *)message {
[self setMessage:message];
[self layoutIfNeeded];
CGFloat cellHeight = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height+1;
return cellHeight;
}
如果消息加載過(guò)快煌张,cell的出現(xiàn)方式就會(huì)有問(wèn)題:
GIF圖不是特別明顯,可以自己運(yùn)行demo看效果
使用YYTextLayout