0. cell 的id 可以用代码注册 也可以在storyboard中注册
1. cell 的创建 identifier
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//判断数据源类型
if ([self.dataSources[indexPath.row] isKindOfClass:[NSString class]]) {//显示时间cell
XMGTimeCell *timeCell = [tableView dequeueReusableCellWithIdentifier:@"TimeCell"];
timeCell.timeLabel.text = self.dataSources[indexPath.row];
return timeCell;
}
//1.先获取消息模型
EMMessage *message = self.dataSources[indexPath.row];
// EMMessage
/* from:xmgtest1 to:xmgtest7 发送方(自己)
* from:xmgtest7 to:xmgtest1 接收方 (好友)
*/
XMGChatCell *cell = nil;
if ([message.from isEqualToString:self.buddy.username]) {//接收方
cell = [tableView dequeueReusableCellWithIdentifier:ReceiverCell];
}else{//发送方
cell = [tableView dequeueReusableCellWithIdentifier:SenderCell];
}
//显示内容
cell.message = message;
return cell;
}
1.5 labe 只用设置leading 和 top 约束
注意labe 只用设置leading 和 top 约束,Trading 和bottom 是根据内容来的
2. 设置label自动换行
Label.numbersOfLines= 0;
Label preferred width = 345;
3. 设置背景imageView 和 label 的frame 相同
选中两个控件 四边距对齐
Leading edges
Trading edges
Top edges
Bottom edges
全部为0
4、设置背景图片合理拉伸 (聊天背景泡泡)
Stretching
X y width height
0 0 1 1
改为
0.5 0.7 0 0
5、 messageImgeView
设置messageImgeView 上下左右 比 label 的frame 外拉伸一点
设置constrain 约束
6.不同聊天内容格式的处理
-(void)setMessage:(EMMessage *)message{
//重用时,把聊天图片控件移除
[self.chatImgView removeFromSuperview];
_message = message;
// 1.获取消息体
id body = message.messageBodies[0];
if ([body isKindOfClass:[EMTextMessageBody class]]) {//文本消息
EMTextMessageBody *textBody = body;
self.messageLabel.text = textBody.text;
}else if([body isKindOfClass:[EMVoiceMessageBody class]]){//语音消息
self.messageLabel.attributedText = [self voiceAtt];
}else if([body isKindOfClass:[EMImageMessageBody class]]){//图片消息
[self showImage];
}
else{
self.messageLabel.text = @"未知类型";
}
}
7.处理语音
#pragma mark 返回语音富文本
-(NSAttributedString *)voiceAtt{
// 创建一个可变的富文本
NSMutableAttributedString *voiceAttM = [[NSMutableAttributedString alloc] init];
// 1.接收方: 富文本 = 图片 + 时间
if ([self.reuseIdentifier isEqualToString:ReceiverCell]) {
// 1.1接收方的语音图片
UIImage *receiverImg = [UIImage imageNamed:@"chat_receiver_audio_playing_full"];
// 1.2创建图片附件
NSTextAttachment *imgAttachment = [[NSTextAttachment alloc] init];
imgAttachment.image = receiverImg;
imgAttachment.bounds = CGRectMake(0, -7, 30, 30);
// 1.3图片富文本
NSAttributedString *imgAtt = [NSAttributedString attributedStringWithAttachment:imgAttachment];
[voiceAttM appendAttributedString:imgAtt];
// 1.4.创建时间富文本
// 获取时间
EMVoiceMessageBody *voiceBody = self.message.messageBodies[0];
NSInteger duration = voiceBody.duration;
NSString *timeStr = [NSString stringWithFormat:@"%ld'",duration];
NSAttributedString *timeAtt = [[NSAttributedString alloc] initWithString:timeStr];
[voiceAttM appendAttributedString:timeAtt];
}else{
// 2.发送方:富文本 = 时间 + 图片
// 2.1 拼接时间
// 获取时间
EMVoiceMessageBody *voiceBody = self.message.messageBodies[0];
NSInteger duration = voiceBody.duration;
NSString *timeStr = [NSString stringWithFormat:@"%ld'",duration];
NSAttributedString *timeAtt = [[NSAttributedString alloc] initWithString:timeStr];
[voiceAttM appendAttributedString:timeAtt];
// 2.1拼接图片
UIImage *receiverImg = [UIImage imageNamed:@"chat_sender_audio_playing_full"];
// 创建图片附件
NSTextAttachment *imgAttachment = [[NSTextAttachment alloc] init];
imgAttachment.image = receiverImg;
imgAttachment.bounds = CGRectMake(0, -7, 30, 30);
// 图片富文本
NSAttributedString *imgAtt = [NSAttributedString attributedStringWithAttachment:imgAttachment];
[voiceAttM appendAttributedString:imgAtt];
}
return [voiceAttM copy];
}
8.处理图片
-(void)showImage{
// 获取图片消息体
EMImageMessageBody *imgBody = self.message.messageBodies[0];
CGRect thumbnailFrm = (CGRect){0,0,imgBody.thumbnailSize};
// CGRect thumbnailFrm = (CGRect){0,0,imgBody.size};
// 设置Label的尺寸足够显示UIImageView
NSTextAttachment *imgAttach = [[NSTextAttachment alloc] init];
imgAttach.bounds = thumbnailFrm;
NSAttributedString *imgAtt = [NSAttributedString attributedStringWithAttachment:imgAttach];
self.messageLabel.attributedText = imgAtt;
//1.cell里添加一个UIImageView
[self.messageLabel addSubview:self.chatImgView];
//2.设置图片控件为缩略图的尺寸
self.chatImgView.frame = thumbnailFrm;
//3.下载图片
// NSLog(@"thumbnailLocalPath %@",imgBody.thumbnailLocalPath);
// NSLog(@"thumbnailRemotePath %@",imgBody.thumbnailRemotePath);
NSFileManager *manager = [NSFileManager defaultManager];
// 如果本地图片存在,直接从本地显示图片
UIImage *palceImg = [UIImage imageNamed:@"downloading"];
if ([manager fileExistsAtPath:imgBody.thumbnailLocalPath]) {
#warning 本地路径使用fileURLWithPath方法
[self.chatImgView sd_setImageWithURL:[NSURL fileURLWithPath:imgBody.thumbnailLocalPath] placeholderImage:palceImg];
}else{
// 如果本地图片不存,从网络加载图片
[self.chatImgView sd_setImageWithURL:[NSURL URLWithString:imgBody.thumbnailRemotePath] placeholderImage:palceImg];
}
}
9.发送类型的两种cell 可以 使用同一个类,id不同就可以了
10.设置行高
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
//时间cell的高度是固定
if ([self.dataSources[indexPath.row] isKindOfClass:[NSString class]]) {
return 18;
}
// 设置label的数据
// 1.获取消息模型
EMMessage *msg = self.dataSources[indexPath.row];
self.chatCellTool.message = msg;
// self.chatCellTool.messageLabel.text = self.dataSources[indexPath.row];
return [self.chatCellTool cellHeghit];
}
/** 返回cell的高度*/
-(CGFloat)cellHeghit{
//1.重新布局子控件
[self layoutIfNeeded];
return 5 + 10 + self.messageLabel.bounds.size.height + 10 + 5;
}
10.5注意接受好友回复的时候是谁回复的
11.加载本地聊天记录
-(void)loadLocalChatRecords{
//假设在数组的第一位置添加时间
// [self.dataSources addObject:@"16:06"];
// 要获取本地聊天记录使用 会话对象
EMConversation *conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:self.buddy.username conversationType:eConversationTypeChat];
self.conversation = conversation;
// 加载与当前聊天用户所有聊天记录
NSArray *messages = [conversation loadAllMessages];
// 添加到数据源
// [self.dataSources addObjectsFromArray:messages];
for (EMMessage *msgObj in messages) {
[self addDataSourcesWithMessage:msgObj];
}
}
12.输入框高度计算
#pragma mark - UITextView代理 --发送文字
-(void)textViewDidChange:(UITextView *)textView{
// NSLog(@"contentOffset %@",NSStringFromCGPoint(textView.contentOffset));
// 1.计算TextView的高度,
CGFloat textViewH = 0;
CGFloat minHeight = 33;//textView最小的高度
CGFloat maxHeight = 68;//textView最大的高度
// 获取contentSize的高度
CGFloat contentHeight = textView.contentSize.height;
if (contentHeight < minHeight) {
textViewH = minHeight;
}else if (contentHeight > maxHeight){
textViewH = maxHeight;
}else{
textViewH = contentHeight;
}
// 2.监听Send事件--判断最后的一个字符是不是换行字符
if ([textView.text hasSuffix:@"\n"]) {
NSLog(@"发送操作");
[self sendText:textView.text];
// 清空textView的文字
textView.text = nil;
// 发送时,textViewH的高度为33
textViewH = minHeight;
}
// 3.调整整个InputToolBar 高度
self.inputToolBarHegihtConstraint.constant = 6 + 7 + textViewH;
// 加个动画
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
// 4.记光标回到原位
#warning 技巧
[textView setContentOffset:CGPointZero animated:YES];
[textView scrollRangeToVisible:textView.selectedRange];
}
网友评论