高性能的聊天頁(yè)面解決方案
對(duì)聊天列表的高度封裝搂根,可靈活配置頁(yè)面樣式
聊天界面其實(shí)大同小異表窘,所以這里封裝了一個(gè)聊天的組件,使用CoreText和手動(dòng)代碼布局,盡量實(shí)現(xiàn)簡(jiǎn)單,通用荐健,高效,易于維護(hù)琳袄。
項(xiàng)目結(jié)構(gòu)
CDChatListView: UITableView 視圖江场,聊天頁(yè)面主體
CDBaseMsgCell: 實(shí)現(xiàn)消息氣泡基本視圖
CDTextTableViewCell、CDImageTableViewCell窖逗、CDAudioTableViewCell: 繼承自CDBaseMsgCell址否,實(shí)現(xiàn)響應(yīng)功能。
CDSystemTableViewCell: 特殊消息氣泡滑负,實(shí)現(xiàn)系統(tǒng)通知
CellCaculator: tableview布局計(jì)算在张,并提前渲染cell
ChatConfiguration: chatlist配置類組用含,UI定制矮慕,及資源等
子組件
CDLabel: 富文本標(biāo)簽
CDChatInputBox: 輸入框封裝組件
安裝
支持至iOS 11
pod 'CDChatList'
使用
配置 CDChatList
ChatHelpr負(fù)責(zé)ChatHelpr的UI配置,及組件的資源文件設(shè)置
UI配置及資源文件都有默認(rèn)啄骇,所以無(wú)需自定義的話痴鳄,就可以跳過(guò)組件的配置
添加 CDChatList 視圖
CDChatListView *list = [[CDChatListView alloc] initWithFrame:self.view.bounds];
list.msgDelegate = self;
self.listView = list;
[self.view addSubview:self.listView];
CDChatList會(huì)將視圖控制器automaticallyAdjustsScrollViewInsets及contentInsetAdjustmentBehavior設(shè)為NO及Never,并適應(yīng)導(dǎo)航欄高度
消息模型 MessageModalProtocal
可以使用自己的消息模型缸夹,消息模型需遵守MessageModalProtocal痪寻,實(shí)現(xiàn)相關(guān)屬性
組件事件 ChatListProtocol
從組件發(fā)出的消息
消息列表請(qǐng)求加載更多消息
-(void)chatlistLoadMoreMsg: (CDChatMessage)topMessage
callback: (void(^)(CDChatMessageArray))finnished;
消息中的點(diǎn)擊事件
-(void)chatlistClickMsgEvent: (ChatListInfo *)listInfo;
向組件發(fā)消息
添加新的數(shù)據(jù)到底部
-(void)addMessagesToBottom: (CDChatMessageArray)newBottomMsgArr;
更新數(shù)據(jù)源中的某條消息模型(主要是為了更新UI上的消息狀態(tài))
-(void)updateMessage:(CDChatMessage)message;
使用場(chǎng)景
收/發(fā)消息
// 發(fā)
{
MessageModal *modal;
}
-(void)send{
modal = [[MessageModal alloc] init];
modal.msgState = CDMessageStateSending;
modal.createTime = ...;
modal.msg = ...;
modal.msgType = ...;
[chatList addMessagesToBottom: modal];
}
-(void)sendCallBack:(BOOL)isSuccess{
modal.msgState = isSuccess; // 此處應(yīng)處理成枚舉
[chatList updateMessage: modal];
}
// 收
-(void)receivedNewMessage:(MessageModal *)modal{
[chatList addMessagesToBottom: modal];
}
下拉加載更多消息
消息列表被下拉時(shí),觸發(fā)此回調(diào)
-(void)chatlistLoadMoreMsg: (CDChatMessage)topMessage
callback: (void(^)(CDChatMessageArray))finnished
{
// 根據(jù)topMessage 獲取更多消息
NSArray *msgArr = [self getMoreMessageFrom: topMessage amount: 10];
callback(msgArr);
}
消息點(diǎn)擊事件
目前消息體重處理了 文本點(diǎn)擊 及 圖片點(diǎn)擊 事件
-(void)chatlistClickMsgEvent: (ChatListInfo *)listInfo{
if (listInfo.eventType == ChatClickEventTypeTEXT){
// 點(diǎn)擊的文本
listInfo.clickedText
// 點(diǎn)擊的文字位置 防止有相同的可點(diǎn)擊文字
listInfo.range
// 被點(diǎn)擊文本的隱藏信息 e.g. <a title="轉(zhuǎn)人工" href="doTransfer">
listInfo.clickedTextContent
} else if (listInfo.eventType == ChatClickEventTypeIMAGE){
// 圖片
listInfo.image
// 圖片在tableview中的位置
listInfo.msgImageRectInTableView
}
}
TODO
- 自定義消息內(nèi)容匹配