李洪强iOS开发之-环信05_EaseUI 使用指南
2016-08-09 15:16
232 查看
[b]李洪强iOS开发之-环信05_EaseUI 使用指南[/b]
源码地址:
EaseUI工程
Demo3.0工程
第 2 步:参考ChatDemo3.0 导入的方式,直接将EaseUI拖入已经集成SDK的项目中
![](http://docs.easemob.com/_media/im/300iosclientintegration/3.0_ios_easeui_workspace.pic.jpg?w=400&tok=6daf95)
第 2 步:在工程的 AppDelegate 中的以下方法中,调用 EaseUI 对应方法。
也可以直接使用 EaseMessageViewController,通过 EaseMessageViewControllerDelegate 和 EaseMessageViewControllerDataSource 两个协议实现对 EaseMessageViewController 的扩展。
获取自定义消息 cell,根据 messageModel,用户自己判断是否显示自定义消息 cell。如果返回 nil 会显示默认;如果返回 cell 会显示用户自定义消息cell。
通过自定义cell展示动态表情的效果图:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_chatview_customcell.png?w=200&tok=755007)
选中消息的回调
用户选中头像的回调
录音按钮状态的回调
EaseMessageViewControllerDataSource
用户判断消息是否允许长按,返回布尔值;如果用户允许长按,此方法为通知用户触发长按手势,返回布尔值,如果返回 NO 默认方式处理,返回 YES 采用用户自定义的处理方式。
Demo3.0实现的消息长按效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_chatview_menu.png?w=200&tok=ca35ad)
将EMMessage类型转换为符合<IMessageModel>协议的类型,设置用户信息,消息显示用户昵称和头像。
聊天会话页面头像和昵称的效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_chatview.png?w=200&tok=ca0222)
具体发送消息样例:
用户根据 conversationModel 实现,实现自定义会话中最后一条消息文案的显示内容。
会话列表最后一条消息和时间显示的效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_conversation.png?w=200&tok=550165)
EaseConversationListViewControllerDelegate
点击会话列表用户可以根据 conversationModel 自定义处理逻辑。
根据 buddy 获取用户自定信息,联系人列表里展示昵称和头像。
联系人列表头像和昵称的效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_contact.png?w=200&tok=239ab9)
EaseUI 使用指南
简介
EaseUI 封装了 IM 功能常用的控件(如聊天会话、会话列表、联系人列表)。旨在帮助开发者快速集成环信 SDK。源码地址:
EaseUI工程
Demo3.0工程
快速集成
第 1 步:集成 EaseUI 前,首先需要集成环信 iOS SDK,参考:集成文档。第 2 步:参考ChatDemo3.0 导入的方式,直接将EaseUI拖入已经集成SDK的项目中
![](http://docs.easemob.com/_media/im/300iosclientintegration/3.0_ios_easeui_workspace.pic.jpg?w=400&tok=6daf95)
初始化
第 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展示动态表情的效果图:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_chatview_customcell.png?w=200&tok=755007)
选中消息的回调
/*! @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实现的消息长按效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_chatview_menu.png?w=200&tok=ca35ad)
将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; }
聊天会话页面头像和昵称的效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_chatview.png?w=200&tok=ca0222)
聊天会话样式自定义
聊天样式的自定义需要在 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; }
会话列表最后一条消息和时间显示的效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_conversation.png?w=200&tok=550165)
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; }
联系人列表头像和昵称的效果演示:
![](http://docs.easemob.com/_media/start/300iosclientintegration/ios_easeui_contact.png?w=200&tok=239ab9)
相关文章推荐
- Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件
- Delphi for iOS开发指南(9):在iOS应用程序中使用ListBox组件来显示TableView
- Delphi for iOS开发指南(12):在iOS Device中使用地理定位
- IOS开发指南学习——使用MKNetworkKit进行网络请求
- CocoaLumberjack的ios应用开发使用指南
- Delphi for iOS开发指南(5):在iOS应用程序中使用Calendar组件来选择日期
- Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox组件来从列表中选择某一项
- Delphi for iOS开发指南(13):在iOS Device中使用通知中心
- Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页
- 视频聊天插件:AnyChat使用攻略之iOS开发指南
- Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件
- Delphi for iOS开发指南(5):在iOS应用程序中使用Calendar组件来选择日期
- Delphi for iOS开发指南(12):在iOS Device中使用地理定位
- Delphi for iOS开发指南(15):在iOS应用程序中使用SQLite
- [ios 站在巨人的肩膀上开发 之]ASIHttpRequest 使用指南(二)
- Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页
- Delphi for iOS开发指南(14):在iOS应用程序中使用InterBase ToGo
- Delphi for iOS开发指南(15):在iOS应用程序中使用SQLite
- CocoaLumberjack的ios应用开发使用指南
- Delphi for iOS开发指南(14):在iOS应用程序中使用InterBase ToGo