1在聊天控制器.加载聊天记录,并添加到数据源:
/**
* 加载本地的聊天记录
*/
- (void)loadLocalChatRecords
{
EMConversation *conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:self.buddy.username conversationType:eConversationTypeChat];
// 加载与当前聊天用户的所有聊记录
NSArray *messages = [conversation loadAllMessages];
// 添加到数据源
[self.dataSources addObjectsFromArray:messages];
}
2.从上面代码我们注意到dataSoures 存放是消息模型。我们tableView返回cell和计算cell高度都要消息数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.获取消息模型
EMMessage *message = self.dataSources[indexPath.row];
// 2.创建cell
ChatCell *cell = nil;
if ([message.from isEqualToString:self.buddy.username]) { //好友
cell = [tableView dequeueReusableCellWithIdentifier:recivierCell];
}else{ //自己
cell = [tableView dequeueReusableCellWithIdentifier:senderCell];
}
// 3.给cell传递数据模型
cell.message = message;
// 4.返回
return cell;
}
#pragma mark - UITableViewDelegate
/**
* 返回cell的高度
*/
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.获取消息模型传递给cell,让cell有了数据然后调整布局
EMMessage *msg = self.dataSources[indexPath.row];
self.chatCellTool.message = msg;
// 2.必须上面cell有了数据调整完布局,才能得到高度
return [self.chatCellTool cellHeight];
}3.我们上面没有直接设置cell上要显示的数据,而是给cell传递了消息模型:
//
// ChatCell.h
#import <UIKit/UIKit.h>
static NSString *recivierCell = @"recivierCell";
static NSString *senderCell = @"senderCell";
@class EMMessage;
@interface ChatCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *messageLabel;
/**
* 消息模型。内部的set方法 显示文字
*/
@property(nonatomic,strong)EMMessage *message;
/**
* 返回cell的高度
*/
- (CGFloat)cellHeight;
@end//
// ChatCell.m
#import "ChatCell.h"
#import "EaseMob.h"
@implementation ChatCell
- (CGFloat)cellHeight
{
// 1.重新布局子控件(后label的高度已经确定了)
[self layoutIfNeeded];
// 2.返回cell的高度
return self.messageLabel.frame.size.height + 50;
}
- (void)setMessage:(EMMessage *)message
{
_message = message;
// 1.获取消息体
id body = message.messageBodies[0];
if ([body isKindOfClass:[EMTextMessageBody class]]) { //文本消息
EMTextMessageBody *textBody = body;
self.messageLabel.text = textBody.text;
}else{
self.messageLabel.text = @"未知类型";
}
}
@end4.最后聊天控制器的代码如下://
// ChatViewController.m
#import "ChatViewController.h"
#import "ChatCell.h"
#import "EaseMob.h"
@interface ChatViewController ()<UITableViewDataSource,UITableViewDelegate,UITextViewDelegate>
/**
* inputToolbar(输入工具栏)底部的约束
*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputToolbarBottomConstraint;
/**
* 里边存的都是消息模型
*/
@property(nonatomic,strong)NSMutableArray *dataSources;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
/**
* 专门用来计算高度的cell工具对象
*/
@property(nonatomic,strong) ChatCell *chatCellTool;
@end
@implementation ChatViewController
- (NSMutableArray *)dataSources
{
if (!_dataSources) {
_dataSources = [NSMutableArray array];
}
return _dataSources;
}
/**
* 懒加载创建chatCellTool
*/
- (ChatCell *)chatCellTool
{
if (!_chatCellTool) {
//Identifier 用recivierCell或senderCell都可以,因为2个cell其实内部
//Identifier 声明在cell内部的
_chatCellTool = [self.tableView dequeueReusableCellWithIdentifier:senderCell];
}
return _chatCellTool;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 0.设置标题
self.title = self.buddy.username;
// 1.监听键盘的弹出
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// 2.监听键盘的退出
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
// 3.加载本地数据库的聊天记录
[self loadLocalChatRecords];
}
/**
* 加载本地的聊天记录
*/
- (void)loadLocalChatRecords
{
EMConversation *conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:self.buddy.username conversationType:eConversationTypeChat];
// 加载与当前聊天用户的所有聊记录
NSArray *messages = [conversation loadAllMessages];
// 添加到数据源
[self.dataSources addObjectsFromArray:messages];
}
/**
* 键盘退出会调用
*/
- (void)keyboardWillHide:(NSNotification *)notice
{
// inputToolbar回到原位
self.inputToolbarBottomConstraint.constant = 0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
/**
* 键盘弹出会调用
*/
- (void)keyboardWillShow:(NSNotification *)notice
{
// 1.获取键盘高度
CGFloat heigth = [notice.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
// 2.更改inputToolbar底部约束
self.inputToolbarBottomConstraint.constant = heigth;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
/**
* 添加通知要移除,我们可以在这里方法里移除
*/
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark -UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataSources.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.获取消息模型
EMMessage *message = self.dataSources[indexPath.row];
// 2.创建cell
ChatCell *cell = nil;
if ([message.from isEqualToString:self.buddy.username]) { //好友
cell = [tableView dequeueReusableCellWithIdentifier:recivierCell];
}else{ //自己
cell = [tableView dequeueReusableCellWithIdentifier:senderCell];
}
// 3.给cell传递数据模型
cell.message = message;
// 4.返回
return cell;
}
#pragma mark - UITableViewDelegate
/**
* 返回cell的高度
*/
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.获取消息模型传递给cell,让cell有了数据然后调整布局
EMMessage *msg = self.dataSources[indexPath.row];
self.chatCellTool.message = msg;
// 2.必须上面cell有了数据调整完布局,才能得到高度
return [self.chatCellTool cellHeight];
}
#pragma mark - UITextViewDelegate
- (void)textViewDidChange:(UITextView *)textView
{
//监听用户是否点击了键盘的"Send"按钮 -- 判断最后一个字符是否是换行符
if ([textView.text hasSuffix:@"\n"]) {
// 1.发送消息
[self sendMessage:textView.text];
// 2.清空textView中的文字
textView.text = nil;
}
}
/**
* 发送消息
*/
- (void)sendMessage:(NSString *)text
{
// 0.处理字符串中的换行符
text = [text substringToIndex:text.length -1];
// 1.准备创建消息实例需要的参数
EMChatText *chatText = [[EMChatText alloc] initWithText:text];
EMTextMessageBody *textBody = [[EMTextMessageBody alloc] initWithChatObject:chatText];
// 2.创建一个消息实例
EMMessage *msg = [[EMMessage alloc] initWithReceiver:self.buddy.username bodies:@[textBody]];
// 3.发送消息
[[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:nil prepare:^(EMMessage *message, EMError *error) {
// 准备发送
} onQueue:nil completion:^(EMMessage *message, EMError *error) {
// 完成发送
} onQueue:nil];
// 4.把消息添加到数据,然后再刷新表格
[self.dataSources addObject:msg];
[self.tableView reloadData];
// 5.消息显示的tableView滚动到最后一行
[self scrollToBottom];
}
/**
* tableView滚动到最后一行
*/
- (void)scrollToBottom
{
if (self.dataSources.count == 0) return;
NSIndexPath *lastIndex = [NSIndexPath indexPathForRow:self.dataSources.count-1 inSection:0];
[self.tableView scrollToRowAtIndexPath:lastIndex atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
@end
效果演示:
本文详细介绍了一个iOS聊天应用的实现过程,包括如何加载和显示聊天记录、计算单元格的高度以及发送消息等功能。通过具体的代码示例展示了如何使用EaseMob SDK进行聊天记录的管理和展示。
1624

被折叠的 条评论
为什么被折叠?



