李洪強iOS開發之-環信05_EaseUI 使用指南


李洪強iOS開發之-環信05_EaseUI 使用指南

EaseUI 使用指南


EaseUI 封裝了 IM 功能常用的控件(如聊天會話、會話列表、聯系人列表)。旨在幫助開發者快速集成環信 SDK。

源碼地址:

第 1 步:集成 EaseUI 前,首先需要集成環信 iOS SDK,參考:集成文檔

第 2 步:參考ChatDemo3.0 導入的方式,直接將EaseUI拖入已經集成SDK的項目中

第 1 步:引入相關頭文件 #import “EaseUI.h”。

第 2 步:在工程的 AppDelegate 中的以下方法中,調用 EaseUI 對應方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[EaseSDKHelper shareHelper] easemobApplication:application didFinishLaunchingWithOptions:launchOptions appkey:@"douser#istore" apnsCertName:@"istore_dev" otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}]; return YES; }

創建聊天會話、傳遞用戶或群 ID 和會話類型(EMConversationType)。

EaseMessageViewController *chatController = [[EaseMessageViewController alloc] initWithConversationChatter:@"8001" conversationType:EMConversationTypeChat];

EaseUI 提供現成的聊天會話 ViewController,可以通過繼承 EaseMessageViewController 方式(參考 ChatDemo-UI3.0 中 ChatViewController)實現對聊天會話的擴展。

也可以直接使用 EaseMessageViewController,通過 EaseMessageViewControllerDelegate 和 EaseMessageViewControllerDataSource 兩個協議實現對 EaseMessageViewController 的擴展。

實現自定義聊天樣式

EaseMessageViewControllerDelegate

獲取自定義消息 cell,根據 messageModel,用戶自己判斷是否顯示自定義消息 cell。如果返回 nil 會顯示默認;如果返回 cell 會顯示用戶自定義消息cell。

/*!
 @method
 @brief 獲取消息自定義cell
 @discussion 用戶根據messageModel判斷是否顯示自定義cell。返回nil顯示默認cell,否則顯示用戶自定義cell
 @param tableView 當前消息視圖的tableView
 @param messageModel 消息模型
 @result 返回用戶自定義cell
 */
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)messageModel;   /*! @method @brief 獲取消息cell高度 @discussion 用戶根據messageModel判斷,是否自定義顯示cell的高度 @param viewController 當前消息視圖 @param messageModel 消息模型 @param cellWidth 視圖寬度 @result 返回用戶自定義cell */ - (CGFloat)messageViewController:(EaseMessageViewController *)viewController heightForMessageModel:(id<IMessageModel>)messageModel withCellWidth:(CGFloat)cellWidth;   //具體創建自定義Cell的樣例: - (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model { //樣例為如果消息是文本消息顯示用戶自定義cell if (model.bodyType == eMessageBodyType_Text) { NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model]; //CustomMessageCell為用戶自定義cell,繼承了EaseBaseMessageCell CustomMessageCell *cell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } cell.model = model; return cell; } return nil; }   - (CGFloat)messageViewController:(EaseMessageViewController *)viewController heightForMessageModel:(id<IMessageModel>)messageModel withCellWidth:(CGFloat)cellWidth { //樣例為如果消息是文本消息使用用戶自定義cell的高度 if (messageModel.bodyType == EMMessageBodyTypeText) { //CustomMessageCell為用戶自定義cell,繼承了EaseBaseMessageCell return [CustomMessageCell cellHeightWithModel:messageModel]; } return 0.f; }

通過自定義cell展示動態表情的效果圖:

選中消息的回調

/*!
 @method
 @brief 選中消息的回調
 @discussion 用戶根據messageModel判斷,是否自定義處理消息選中時間。返回YES為自定義處理,返回NO為默認處理
 @param viewController 當前消息視圖
 @param messageModel 消息模型
 @result 是否采用自定義處理
 */
- (BOOL)messageViewController:(EaseMessageViewController *)viewController didSelectMessageModel:(id<IMessageModel>)messageModel;   //選中消息回調的樣例: - (BOOL)messageViewController:(EaseMessageViewController *)viewController didSelectMessageModel:(id<IMessageModel>)messageModel { BOOL flag = NO; //樣例為如果消息是文件消息用戶自定義處理選中邏輯 switch (messageModel.bodyType) { case EMMessageBodyTypeImage: case EMMessageBodyTypeLocation: case EMMessageBodyTypeVideo: case EMMessageBodyTypeVoice: break; case EMMessageBodyTypeFile: { flag = YES; NSLog(@"用戶自定義實現"); } break; default: break; } return flag; }

用戶選中頭像的回調

/*!
 @method
 @brief 點擊消息頭像
 @discussion 獲取用戶點擊頭像回調
 @param viewController 當前消息視圖
 @param messageModel 消息模型
 @result
 */
- (void)messageViewController:(EaseMessageViewController *)viewController didSelectAvatarMessageModel:(id<IMessageModel>)messageModel;   //獲取用戶點擊頭像回調的樣例: - (void)messageViewController:(EaseMessageViewController *)viewController didSelectAvatarMessageModel:(id<IMessageModel>)messageModel { //UserProfileViewController用戶自定義的個人信息視圖 //樣例的邏輯是選中消息頭像后,進入該消息發送者的個人信息 UserProfileViewController *userprofile = [[UserProfileViewController alloc] initWithUsername:messageModel.message.from]; [self.navigationController pushViewController:userprofile animated:YES]; }

錄音按鈕狀態的回調

/*!
 @method
 @brief 底部錄音功能按鈕狀態回調
 @discussion 獲取底部錄音功能按鈕狀態回調,根據EaseRecordViewType,用戶自定義處理UI的邏輯
 @param viewController 當前消息視圖
 @param recordView 錄音視圖
 @param type 錄音按鈕當前狀態
 @result
 */
- (void)messageViewController:(EaseMessageViewController *)viewController didSelectRecordView:(UIView *)recordView withEvenType:(EaseRecordViewType)type;   //錄音按鈕狀態的回調樣例: - (void)messageViewController:(EaseMessageViewController *)viewController didSelectRecordView:(UIView *)recordView withEvenType:(EaseRecordViewType)type { /* EaseRecordViewTypeTouchDown,//錄音按鈕按下 EaseRecordViewTypeTouchUpInside,//手指在錄音按鈕內部時離開 EaseRecordViewTypeTouchUpOutside,//手指在錄音按鈕外部時離開 EaseRecordViewTypeDragInside,//手指移動到錄音按鈕內部 EaseRecordViewTypeDragOutside,//手指移動到錄音按鈕外部 */ //根據type類型,用戶自定義處理UI的邏輯 switch (type) { case EaseRecordViewTypeTouchDown: { if ([self.recordView isKindOfClass:[EaseRecordView class]]) { [(EaseRecordView *)self.recordView recordButtonTouchDown]; } } break; case EaseRecordViewTypeTouchUpInside: { if ([self.recordView isKindOfClass:[EaseRecordView class]]) { [(EaseRecordView *)self.recordView recordButtonTouchUpInside]; } [self.recordView removeFromSuperview]; } break; case EaseRecordViewTypeTouchUpOutside: { if ([self.recordView isKindOfClass:[EaseRecordView class]]) { [(EaseRecordView *)self.recordView recordButtonTouchUpOutside]; } [self.recordView removeFromSuperview]; } break; case EaseRecordViewTypeDragInside: { if ([self.recordView isKindOfClass:[EaseRecordView class]]) { [(EaseRecordView *)self.recordView recordButtonDragInside]; } } break; case EaseRecordViewTypeDragOutside: { if ([self.recordView isKindOfClass:[EaseRecordView class]]) { [(EaseRecordView *)self.recordView recordButtonDragOutside]; } } break; default: break; } }

EaseMessageViewControllerDataSource

用戶判斷消息是否允許長按,返回布爾值;如果用戶允許長按,此方法為通知用戶觸發長按手勢,返回布爾值,如果返回 NO 默認方式處理,返回 YES 采用用戶自定義的處理方式。

/*!
 @method
 @brief 是否允許長按
 @discussion 獲取是否允許長按的回調,默認是NO
 @param viewController 當前消息視圖
 @param indexPath 長按消息對應的indexPath
 @result
 */
- (BOOL)messageViewController:(EaseMessageViewController *)viewController canLongPressRowAtIndexPath:(NSIndexPath *)indexPath;   /*! @method @brief 觸發長按手勢 @discussion 獲取觸發長按手勢的回調,默認是NO @param viewController 當前消息視圖 @param indexPath 長按消息對應的indexPath @result */ - (BOOL)messageViewController:(EaseMessageViewController *)viewController didLongPressRowAtIndexPath:(NSIndexPath *)indexPath;   //長按收拾回調樣例: - (BOOL)messageViewController:(EaseMessageViewController *)viewController canLongPressRowAtIndexPath:(NSIndexPath *)indexPath { //樣例給出的邏輯是所有cell都允許長按 return YES; }   - (BOOL)messageViewController:(EaseMessageViewController *)viewController didLongPressRowAtIndexPath:(NSIndexPath *)indexPath { //樣例給出的邏輯是長按cell之后顯示menu視圖 id object = [self.dataArray objectAtIndex:indexPath.row]; if (![object isKindOfClass:[NSString class]]) { EaseMessageCell *cell = (EaseMessageCell *)[self.tableView cellForRowAtIndexPath:indexPath]; [cell becomeFirstResponder]; self.menuIndexPath = indexPath; [self _showMenuViewController:cell.bubbleView andIndexPath:indexPath messageType:cell.model.bodyType]; } return YES; }

Demo3.0實現的消息長按效果演示:

將EMMessage類型轉換為符合<IMessageModel>協議的類型,設置用戶信息,消息顯示用戶昵稱和頭像。

/*!
 @method
 @brief 將EMMessage類型轉換為符合<IMessageModel>協議的類型
 @discussion 將EMMessage類型轉換為符合<IMessageModel>協議的類型,設置用戶信息,消息顯示用戶昵稱和頭像
 @param viewController 當前消息視圖
 @param EMMessage 聊天消息對象類型
 @result 返回<IMessageModel>協議的類型
 */
- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController modelForMessage:(EMMessage *)message;   //具體樣例: - (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController modelForMessage:(EMMessage *)message { //用戶可以根據自己的用戶體系,根據message設置用戶昵稱和頭像 id<IMessageModel> model = nil; model = [[EaseMessageModel alloc] initWithMessage:message]; model.avatarImage = [UIImage imageNamed:@"EaseUIResource.bundle/user"];//默認頭像 model.avatarURLPath = @"";//頭像網絡地址 model.nickname = @"昵稱";//用戶昵稱 return model; }

聊天會話頁面頭像和昵稱的效果演示:

聊天會話樣式自定義

聊天樣式的自定義需要在 EaseMessageViewController 中 viewDidload 結束前設置。

//@property中帶有UI_APPEARANCE_SELECTOR,都可以通過set的形式設置樣式,具體可以參考EaseBaseMessageCell.h,EaseMessageCell.h
 
[[EaseBaseMessageCell appearance] setSendBubbleBackgroundImage:[[UIImage imageNamed:@"chat_sender_bg"] stretchableImageWithLeftCapWidth:5 topCapHeight:35]];//設置發送氣泡 [[EaseBaseMessageCell appearance] setRecvBubbleBackgroundImage:[[UIImage imageNamed:@"chat_receiver_bg"] stretchableImageWithLeftCapWidth:35 topCapHeight:35]];//設置接收氣泡   [[EaseBaseMessageCell appearance] setAvatarSize:40.f];//設置頭像大小 [[EaseBaseMessageCell appearance] setAvatarCornerRadius:20.f];//設置頭像圓角

EaseSDKHelper 封裝了發送消息的方法。

具體發送消息樣例:

/*
 EMChatTypeChat            單聊消息
 EMChatTypeGroupChat       群聊消息
 EMChatTypeChatRoom        聊天室消息
*/
 
//發送文字消息 EMMessage *message = [EaseSDKHelper sendTextMessage:@"要發送的消息" to:@"6001"//接收方 messageType:EMChatTypeChat//消息類型 messageExt:nil]; //擴展信息 //發送位置消息 EMMessage *message = [EaseSDKHelper sendLocationMessageWithLatitude:35.1//經度 longitude:35.1//緯度 address:"地址" to:@"6001"//接收方 messageType:EMChatTypeChat//消息類型 messageExt:nil];//擴展信息   //發送圖片消息 EMMessage *message = [EaseSDKHelper sendImageMessageWithImageData:imageData//發送的圖片數據NSData to:@"6001"//接收方 messageType:EMChatTypeChat//消息類型 messageExt:nil];//擴展信息   //發送音頻消息 EMMessage *message = [EaseSDKHelper sendVoiceMessageWithLocalPath:localPath//音頻本地地址 duration:duration//語音的時長,單位是秒 to:@"6001"//接收方 messageType:EMChatTypeChat//消息類型 messageExt:nil];//擴展信息   //發送視頻文件消息 EMMessage *message = [EaseSDKHelper sendVideoMessageWithURL:url//發送的視頻地址 to:@"6001"//接收方 messageType:EMChatTypeChat//消息類型 messageExt:nil];//擴展信息   //發送構造成功的消息 [[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {   }]; 
 
EaseConversationListViewController *chatListVC = [[EaseConversationListViewController alloc] init];

EaseConversationListViewControllerDataSource

用戶根據 conversationModel 實現,實現自定義會話中最后一條消息文案的顯示內容。

/*!
 @method
 @brief 獲取最后一條消息顯示的內容
 @discussion 用戶根據conversationModel實現,實現自定義會話中最后一條消息文案的顯示內容
 @param conversationListViewController 當前會話列表視圖
 @param IConversationModel 會話模型
 @result 返回用戶最后一條消息顯示的內容
 */
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel;     /*! @method @brief 獲取最后一條消息顯示的時間 @discussion 用戶可以根據conversationModel,自定義實現會話列表中時間文案的顯示內容 @param conversationListViewController 當前會話列表視圖 @param IConversationModel 會話模型 @result 返回用戶最后一條消息時間的顯示文案 */ - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel;   //最后一條消息展示內容樣例 - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel { NSString *latestMessageTitle = @""; EMMessage *lastMessage = [conversationModel.conversation latestMessage]; if (lastMessage) { EMMessageBody *messageBody = lastMessage.body; switch (messageBody.type) { case EMMessageBodyTypeImage:{ latestMessageTitle = NSLocalizedString(@"message.image1", @"[image]"); } break; case EMMessageBodyTypeText:{ // 表情映射。 NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text]; latestMessageTitle = didReceiveText; if ([lastMessage.ext objectForKey:MESSAGE_ATTR_IS_BIG_EXPRESSION]) { latestMessageTitle = @"[動畫表情]"; } } break; case EMMessageBodyTypeVoice:{ latestMessageTitle = NSLocalizedString(@"message.voice1", @"[voice]"); } break; case EMMessageBodyTypeLocation: { latestMessageTitle = NSLocalizedString(@"message.location1", @"[location]"); } break; case EMMessageBodyTypeVideo: { latestMessageTitle = NSLocalizedString(@"message.video1", @"[video]"); } break; case EMMessageBodyTypeFile: { latestMessageTitle = NSLocalizedString(@"message.file1", @"[file]"); } break; default: { } break; } }   return latestMessageTitle; }   //最后一條消息展示時間樣例 - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel { NSString *latestMessageTime = @""; EMMessage *lastMessage = [conversationModel.conversation latestMessage];; if (lastMessage) { latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp]; } return latestMessageTime; }

會話列表最后一條消息和時間顯示的效果演示:

EaseConversationListViewControllerDelegate

點擊會話列表用戶可以根據 conversationModel 自定義處理邏輯。

/*!
 @method
 @brief 獲取點擊會話列表的回調
 @discussion 獲取點擊會話列表的回調后,點擊會話列表用戶可以根據conversationModel自定義處理邏輯
 @param conversationListViewController 當前會話列表視圖
 @param IConversationModel 會話模型
 @result
 */
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController didSelectConversationModel:(id<IConversationModel>)conversationModel;   //會話列表點擊的回調樣例 - (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController didSelectConversationModel:(id<IConversationModel>)conversationModel { //樣例展示為根據conversationModel,進入不同的會話ViewController if (conversationModel) { EMConversation *conversation = conversationModel.conversation; if (conversation) { if ([[RobotManager sharedInstance] isRobotWithUsername:conversation.conversationId]) { RobotChatViewController *chatController = [[RobotChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type]; chatController.title = [[RobotManager sharedInstance] getRobotNickWithUsername:conversation.conversationId]; [self.navigationController pushViewController:chatController animated:YES]; } else { ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type]; chatController.title = conversationModel.title; [self.navigationController pushViewController:chatController animated:YES]; } } [[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil]; [self.tableView reloadData]; } }
 

聯系人列表初始化

EaseUsersListViewController *listViewController = [[EaseUsersListViewController alloc] init];

聯系人列表擴展

需要實現 EMUserListViewControllerDataSource。

根據 buddy 獲取用戶自定信息,聯系人列表里展示昵稱和頭像。

/*!
 @method
 @brief 獲取用戶模型
 @discussion 根據buddy獲取用戶自定信息,聯系人列表里展示昵稱和頭像
 @param userListViewController 當前聯系人視圖
 @param buddy 好友的信息描述類
 @result 返回用戶模型
 */
- (id<IUserModel>)userListViewController:(EaseUsersListViewController *)userListViewController modelForBuddy:(NSString *)buddy;   //聯系人列表擴展樣例 - (id<IUserModel>)userListViewController:(EaseUsersListViewController *)userListViewController modelForBuddy:(NSString *)buddy { //用戶可以根據自己的用戶體系,根據buddy設置用戶昵稱和頭像 id<IUserModel> model = nil; model = [[EaseUserModel alloc] initWithBuddy:buddy]; model.avatarURLPath = @"";//頭像網絡地址 model.nickname = @"昵稱";//用戶昵稱 return model; }

聯系人列表頭像和昵稱的效果演示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM