集成環(huán)信的即時通訊

上官網(wǎng)注冊賬號

首先來到環(huán)信的官網(wǎng),然后登陸.沒有賬號先注冊一個.

進去之后創(chuàng)建應用,如圖

創(chuàng)建應用界面

點擊確定后,來到這個界面,只需要記住應用標示(APPKey)就行,待會兒會在代碼里用到它.

屏幕快照 2016-01-04 下午7.18.38.png

然后用cocoapods導入環(huán)信SDK,大家可以通過這篇博客來安裝cocoapods.

創(chuàng)建項目

打開終端,輸入cd,然后將項目入進去回車,就跳到項目地址,輸入命令:pod

init,然后會生成一個Podfile,雙擊這個文件,將里面的東西全刪了,然后輸入:pod 'EaseMobSDK',然后在終端輸入命令:pod

install(如果不行可以試試:pod install --verbose

--no-repo-update).接下來就等著SDK下載安裝到項目里了,大概幾分鐘后就好了.這時候需要雙擊.xcworkspace的那個文件進去.SDK集成就完成了(不知道為什么官方文檔里面寫的集成特別復雜,需要導入各種框架,修改很多東西,其實只要終端一條指令就OK了).

AppDelegate

大家還記得剛才的APPKey吧,在AppDelegate里面需要注冊使用.

#import"AppDelegate.h"#import"ViewController.h"#import@interfaceAppDelegate()@end@implementationAppDelegate- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {? ? _window = [[UIWindowalloc]initWithFrame:[UIScreenmainScreen].bounds];? ? _window.backgroundColor = [UIColorwhiteColor];? ? [_window makeKeyAndVisible];UINavigationController*nav = [[UINavigationControlleralloc]initWithRootViewController:[[ViewController alloc]init]];? ? _window.rootViewController = nav;//注冊環(huán)信[[EaseMob sharedInstance]registerSDKWithAppKey:@"xmh123#cdxmh"apnsCertName:@""];returnYES;}- (void)applicationWillResignActive:(UIApplication*)application {// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.}- (void)applicationDidEnterBackground:(UIApplication*)application {? ? [[EaseMob sharedInstance] applicationDidEnterBackground:application];}- (void)applicationWillEnterForeground:(UIApplication*)application {? ? [[EaseMob sharedInstance] applicationWillEnterForeground:application];}- (void)applicationDidBecomeActive:(UIApplication*)application {// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.}- (void)applicationWillTerminate:(UIApplication*)application {? ? [[EaseMob sharedInstance]applicationWillTerminate:application];}@end

登陸界面

登陸界面

看看這部分的代碼吧.

#import"ViewController.h"#import"RegisterViewController.h"#import"FriendListViewController.h"#import@interfaceViewController()@property(nonatomic,strong)UITextField*userNameTextField;//用戶名@property(nonatomic,strong)UITextField*passwordTextField;//密碼@property(nonatomic,strong)UIButton*loginButton;//登陸按鈕@property(nonatomic,strong)UIButton*registerButton;//注冊按鈕@end@implementationViewController- (void)viewDidLoad {? ? [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];self.navigationController.navigationBar.translucent =NO;self.title =@"登陸界面";UILabel*usernameLabel = [[UILabelalloc]initWithFrame:CGRectMake(20,100,80,50)];? ? usernameLabel.text =@"用戶名";? ? usernameLabel.font = [UIFontsystemFontOfSize:25];? ? [self.view addSubview:usernameLabel];? ? _userNameTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x + usernameLabel.frame.size.width +10, usernameLabel.frame.origin.y,250,50)];? ? _userNameTextField.borderStyle =3;? ? _userNameTextField.placeholder =@"請輸入用戶名";? ? [self.view addSubview:_userNameTextField];UILabel*passwordLabel = [[UILabelalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x, usernameLabel.frame.origin.y + usernameLabel.frame.size.height +10, usernameLabel.frame.size.width, usernameLabel.frame.size.height)];? ? passwordLabel.text =@"密碼";? ? passwordLabel.font = [UIFontsystemFontOfSize:25];? ? [self.view addSubview:passwordLabel];? ? _passwordTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(_userNameTextField.frame.origin.x, passwordLabel.frame.origin.y, _userNameTextField.frame.size.width, _userNameTextField.frame.size.height)];? ? _passwordTextField.placeholder =@"請輸入密碼";? ? _passwordTextField.borderStyle =3;? ? [self.view addSubview:_passwordTextField];? ? _loginButton = [UIButtonbuttonWithType:UIButtonTypeSystem];? ? _loginButton.frame =CGRectMake(170,300,50,50);? ? _loginButton.titleLabel.font = [UIFontsystemFontOfSize:25];? ? [_loginButton setTitle:@"登陸"forState:UIControlStateNormal];? ? [_loginButton addTarget:selfaction:@selector(didClickLoginButton) forControlEvents:UIControlEventTouchUpInside];? ? [self.view addSubview:_loginButton];? ? _registerButton = [UIButtonbuttonWithType:UIButtonTypeSystem];? ? _registerButton.frame =CGRectMake(170,410,50,50);? ? _registerButton.titleLabel.font = [UIFontsystemFontOfSize:25];? ? [_registerButton setTitle:@"注冊"forState:UIControlStateNormal];? ? [_registerButton addTarget:selfaction:@selector(jumpToRegister) forControlEvents:UIControlEventTouchUpInside];? ? [self.view addSubview:_registerButton];}-(void)didClickLoginButton{? ? [[EaseMob sharedInstance].chatManager asyncLoginWithUsername:_userNameTextField.text password:_passwordTextField.text completion:^(NSDictionary*loginInfo, EMError *error) {if(!error) {//如果驗證用戶名和密碼沒有問題就跳轉(zhuǎn)到好友列表界面[self.navigationController pushViewController:[[FriendListViewController alloc]init] animated:YES];? ? ? ? }else{// 顯示錯誤信息的警告NSLog(@"%@",error);? ? ? ? }? ? } onQueue:dispatch_get_main_queue()];}-(void)jumpToRegister{//跳轉(zhuǎn)到注冊界面RegisterViewController *registerVC = [[RegisterViewController alloc]init];? ? [self.navigationController presentViewController:registerVC animated:YEScompletion:nil];}- (void)didReceiveMemoryWarning {? ? [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}@end

這個界面很簡單,大部分都是界面搭建,當點擊登陸時會調(diào)用

[[EaseMob sharedInstance].chatManagerasyncLoginWithUsername:_userNameTextField.textpassword:_passwordTextField.textcompletion:^(NSDictionary *loginInfo, EMError *error)

這個方法有2個參數(shù),一個用戶名,一個是密碼,很容易猜到這就是驗證你的用戶名和密碼是否正確,如果正確就跳轉(zhuǎn)到好友列表界面,如果不對就會在控制臺打印相應的錯誤.

點擊注冊就跳轉(zhuǎn)到注冊界面.

注冊界面

注冊界面

由于第一次登陸時沒有賬號,所以先得注冊.先看看代碼:

#import"RegisterViewController.h"#import@interfaceRegisterViewController()@property(nonatomic,strong)UITextField*userNameTextField;//用戶名@property(nonatomic,strong)UITextField*passwordTextField;//密碼@property(nonatomic,strong)UIButton*registerButton;//注冊按鈕@end@implementationRegisterViewController- (void)viewDidLoad {? ? [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];self.navigationController.navigationBar.translucent =NO;self.title =@"登陸界面";UILabel*usernameLabel = [[UILabelalloc]initWithFrame:CGRectMake(20,100,80,50)];? ? usernameLabel.text =@"用戶名";? ? usernameLabel.font = [UIFontsystemFontOfSize:25];? ? [self.view addSubview:usernameLabel];? ? _userNameTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x + usernameLabel.frame.size.width +10, usernameLabel.frame.origin.y,250,50)];? ? _userNameTextField.borderStyle =3;? ? _userNameTextField.placeholder =@"請輸入用戶名";? ? [self.view addSubview:_userNameTextField];UILabel*passwordLabel = [[UILabelalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x, usernameLabel.frame.origin.y + usernameLabel.frame.size.height +10, usernameLabel.frame.size.width, usernameLabel.frame.size.height)];? ? passwordLabel.text =@"密碼";? ? passwordLabel.font = [UIFontsystemFontOfSize:25];? ? [self.view addSubview:passwordLabel];? ? _passwordTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(_userNameTextField.frame.origin.x, passwordLabel.frame.origin.y, _userNameTextField.frame.size.width, _userNameTextField.frame.size.height)];? ? _passwordTextField.placeholder =@"請輸入密碼";? ? _passwordTextField.borderStyle =3;? ? [self.view addSubview:_passwordTextField];? ? _registerButton = [UIButtonbuttonWithType:UIButtonTypeSystem];? ? _registerButton.frame =CGRectMake(170,330,50,50);? ? _registerButton.titleLabel.font = [UIFontsystemFontOfSize:25];? ? [_registerButton setTitle:@"注冊"forState:UIControlStateNormal];? ? [_registerButton addTarget:selfaction:@selector(didClickedRegisterButton:) forControlEvents:UIControlEventTouchUpInside];? ? [self.view addSubview:_registerButton];UIButton*backButton = [UIButtonbuttonWithType:UIButtonTypeSystem];? ? backButton.frame =CGRectMake(170,280,50,50);? ? backButton.titleLabel.font = [UIFontsystemFontOfSize:25];? ? [backButton setTitle:@"返回"forState:UIControlStateNormal];? ? [backButton addTarget:selfaction:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];? ? [self.view addSubview:backButton];}-(void)backAction{? ? [selfdismissViewControllerAnimated:YEScompletion:nil];}-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{//點擊屏幕時讓鍵盤回收[_passwordTextField resignFirstResponder];? ? [_userNameTextField resignFirstResponder];}-(void)didClickedRegisterButton:(id)sender{//? 登陸和注冊有3種方法: 1. 同步方法 2. 通過delegate回調(diào)的異步方法项栏。3.block異步方法//其中官方推薦使用block異步方法,所以我這里就用block異步方法//開始注冊[[EaseMob sharedInstance].chatManager asyncRegisterNewAccount:_userNameTextField.text password:_passwordTextField.text withCompletion:^(NSString*username,NSString*password, EMError *error) {if(!error) {NSLog(@"注冊成功");? ? ? ? ? ? [selfdismissViewControllerAnimated:YEScompletion:nil];? ? ? ? }else{NSLog(@"%@",error);? ? ? ? }? ? } onQueue:dispatch_get_main_queue()];}- (void)didReceiveMemoryWarning {? ? [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}/*

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

}

@end

這個界面也特別簡單,除了界面搭建,就只有這個方法:

[[EaseMob sharedInstance].chatManagerasyncRegisterNewAccount:_userNameTextField.textpassword:_passwordTextField.textwithCompletion:^(NSString *username, NSString *password, EMError *error)

一共兩個參數(shù),就是用戶名和密碼,然后判斷用戶名和密碼是否可用,如果可用就返回到登陸界面.

好友列表界面

好友列表界面

這里我只加了一個好友叫xiaomei.

好友界面是怎么樣的呢,大家先看看代碼:

#import"FriendListViewController.h"#import"AddFriendViewController.h"#import"ChatViewController.h"#import@interfaceFriendListViewController()@property(nonatomic,strong)NSMutableArray*listArray;@property(nonatomic,strong)UITableView*tableView;@end@implementationFriendListViewController-(void)viewWillAppear:(BOOL)animated{? ? [superviewWillAppear:animated];? ? }-(void)loadView{? ? [superloadView];self.view.backgroundColor = [UIColorwhiteColor];//左側(cè)注銷按鈕self.navigationItem.leftBarButtonItem = [[UIBarButtonItemalloc]initWithTitle:@"注銷"style:UIBarButtonItemStylePlaintarget:selfaction:@selector(didClickedCancelButton)];self.title =@"好友";? ? [[EaseMob sharedInstance].chatManager asyncFetchBuddyListWithCompletion:^(NSArray*buddyList, EMError *error) {if(!error) {NSLog(@"獲取成功 -- %@", buddyList);? ? ? ? ? ? [_listArray removeAllObjects];? ? ? ? ? ? [_listArray addObjectsFromArray:buddyList];? ? ? ? ? ? [_tableView reloadData];? ? ? ? }? ? } onQueue:dispatch_get_main_queue()];}- (void)viewDidLoad {? ? [superviewDidLoad];? ? _listArray = [NSMutableArraynew];self.navigationItem.rightBarButtonItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:selfaction:@selector(addbuttonAction)];? ? _tableView = [[UITableViewalloc]initWithFrame:self.view.frame];? ? _tableView.delegate =self;? ? _tableView.dataSource =self;? ? _tableView.tableFooterView = [[UIViewalloc]init];? ? [self.view addSubview:_tableView];//簽協(xié)議[ [EaseMob sharedInstance].chatManager addDelegate:selfdelegateQueue:dispatch_get_main_queue()];}-(void)didClickedCancelButton{//注銷用戶[[EaseMob sharedInstance].chatManager asyncLogoffWithUnbindDeviceToken:YES];? ? [self.navigationController popViewControllerAnimated:YES];}-(void)addbuttonAction{? ? [self.navigationController pushViewController:[[AddFriendViewController alloc]init] animated:YES];}# pragma mark - Table View Data Source- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {return_listArray.count;}-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{return50;}- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*identifier =@"cell";UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:identifier];if(!cell) {? ? ? ? cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:identifier];? ? }? ? EMBuddy * buddy = _listArray[indexPath.row];? ? cell.textLabel.text = buddy.username;returncell;}- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {? ? ChatViewController * chatVC = [[ChatViewController alloc]init];? ? EMBuddy * buddy = _listArray[indexPath.row];? ? chatVC.name = buddy.username;? ? [self.navigationController pushViewController:chatVC animated:YES];}-(void)didReceiveBuddyRequest:(NSString*)username message:(NSString*)message{UIAlertController* alertController = [UIAlertControlleralertControllerWithTitle:[NSStringstringWithFormat:@"收到來自%@的請求", username] message:message preferredStyle:(UIAlertControllerStyleAlert)];UIAlertAction* acceptAction = [UIAlertActionactionWithTitle:@"好"style:(UIAlertActionStyleDefault) handler:^(UIAlertAction*? action) {? ? ? ? EMError * error;// 同意好友請求的方法if([[EaseMob sharedInstance].chatManager acceptBuddyRequest:username error:&error] && !error) {NSLog(@"發(fā)送同意成功");? ? ? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{? ? ? ? ? ? ? ? [[EaseMob sharedInstance].chatManager asyncFetchBuddyListWithCompletion:^(NSArray*buddyList, EMError *error) {if(!error) {NSLog(@"獲取成功 -- %@", buddyList);? ? ? ? ? ? ? ? ? ? ? ? [_listArray removeAllObjects];? ? ? ? ? ? ? ? ? ? ? ? [_listArray addObjectsFromArray:buddyList];? ? ? ? ? ? ? ? ? ? ? ? [_tableView reloadData];? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? } onQueue:dispatch_get_main_queue()];? ? ? ? ? ? });? ? ? ? }? ? }];UIAlertAction* rejectAction = [UIAlertActionactionWithTitle:@"滾"style:(UIAlertActionStyleCancel) handler:^(UIAlertAction* _Nonnull action) {? ? ? ? EMError * error;// 拒絕好友請求的方法if([[EaseMob sharedInstance].chatManager rejectBuddyRequest:username reason:@"滾, 快滾!"error:&error] && !error) {NSLog(@"發(fā)送拒絕成功");? ? ? ? }? ? }];? ? [alertController addAction:acceptAction];? ? [alertController addAction:rejectAction];? ? [selfshowDetailViewController:alertController sender:nil];}- (void)didReceiveMemoryWarning {? ? [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}

首先,使用下面這個方法獲取到所有的好友,然后將好友放入你的數(shù)組,這樣好友的信息都在數(shù)組里了

[[EaseMob sharedInstance].chatManager asyncFetchBuddyListWithCompletion:^(NSArray*buddyList, EMError *error) {? ? ? ? if (!error) {? ? ? ? ? ? NSLog(@"獲取成功 -- %@", buddyList);[_listArray removeAllObjects];[_listArray addObjectsFromArray:buddyList];[_tableView reloadData];}? ? } onQueue:dispatch_get_main_queue()];

tableView沒行的信息通過下面這個方法,剛才已經(jīng)把所有好友的信息方法數(shù)組里了,那么就可以通過EMBuddy * buddy =

_listArray[indexPath.row]這個方法獲取單個好友信息,用? cell.textLabel.text =

buddy.username給每個cell的text賦值.

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*identifier =@"cell";UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:identifier];if(!cell) {? ? ? ? cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:identifier];? ? }? ? EMBuddy * buddy = _listArray[indexPath.row];? ? cell.textLabel.text = buddy.username;returncell;}

當別人想加你為好友時,會調(diào)用這個方法.先彈出一個提示框,然后根據(jù)你的選擇而去接受或者拒絕.如果接受,就重新導入一遍數(shù)據(jù),然后刷新tableView.如果拒絕就調(diào)用拒絕的方法.這并不難理解吧.

-(void)didReceiveBuddyRequest:(NSString *)usernamemessage:(NSString *)message{ UIAlertController * alertController = [UIAlertControlleralertControllerWithTitle:[NSStringstringWithFormat:@"收到來自%@的請求", username]message:messagepreferredStyle:(UIAlertControllerStyleAlert)];? ? UIAlertAction * acceptAction = [UIAlertActionactionWithTitle:@"好"style:(UIAlertActionStyleDefault)handler:^(UIAlertAction *? action) {? ? ? ? EMError * error;// 同意好友請求的方法if([[EaseMob sharedInstance].chatManageracceptBuddyRequest:usernameerror:&error] && !error) {? ? ? ? ? ? NSLog(@"發(fā)送同意成功");? ? ? ? ? ? ? ? [[EaseMob sharedInstance].chatManagerasyncFetchBuddyListWithCompletion:^(NSArray *buddyList, EMError *error) {if(!error) {? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"獲取成功 -- %@", buddyList);? ? ? ? ? ? ? ? ? ? ? ? [_listArray removeAllObjects];? ? ? ? ? ? ? ? ? ? ? ? [_listArrayaddObjectsFromArray:buddyList];? ? ? ? ? ? ? ? ? ? ? ? [_tableView reloadData];? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }onQueue:dispatch_get_main_queue()];? ? ? ? }? ? }];? ? UIAlertAction * rejectAction = [UIAlertActionactionWithTitle:@"滾"style:(UIAlertActionStyleCancel)handler:^(UIAlertAction * _Nonnull action) {? ? ? ? EMError * error;// 拒絕好友請求的方法if([[EaseMob sharedInstance].chatManagerrejectBuddyRequest:usernamereason:@"滾, 快滾!"error:&error] && !error) {? ? ? ? ? ? NSLog(@"發(fā)送拒絕成功");? ? ? ? }? ? }];? ? [alertControlleraddAction:acceptAction];? ? [alertControlleraddAction:rejectAction];? ? [selfshowDetailViewController:alertControllersender:nil];

聊天界面

聊天界面

在看聊天界面之前先需要自定義一個聊天輸入框,就是下面那個帶一個textfield和button的.

DialogBoxView.m

#import"DialogBoxView.h"@interfaceDialogBoxView()@property(nonatomic,strong)UITextField* draftTextField;@property(nonatomic,strong)UIButton* sendButton;@end@implementationDialogBoxView- (instancetype)initWithFrame:(CGRect)frame{self= [superinitWithFrame:frame];if(self) {? ? ? ? [selfinitView];? ? }returnself;}- (void)initView{? ? [selfsetBackgroundColor:[UIColorcolorWithWhite:0.9alpha:1]];? ? _draftTextField = [[UITextFieldalloc] initWithFrame:CGRectMake(5,5,self.frame.size.width -100,self.frame.size.height -10)];? ? [_draftTextField setBorderStyle:(UITextBorderStyleRoundedRect)];? ? [_draftTextField setPlaceholder:@"說點什么呢"];? ? [_draftTextField setFont:[UIFontsystemFontOfSize:13]];? ? [selfaddSubview:_draftTextField];? ? _sendButton = [UIButtonbuttonWithType:(UIButtonTypeCustom)];? ? [_sendButton setFrame:CGRectMake(self.frame.size.width -90,5,85,self.frame.size.height -10)];? ? [_sendButton setBackgroundColor:[UIColorcolorWithRed:1green:0blue:128/255.0alpha:1]];? ? [_sendButton setTitle:@"發(fā)送"forState:(UIControlStateNormal)];? ? [_sendButton setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];? ? [_sendButton.titleLabel setFont:[UIFontboldSystemFontOfSize:15]];? ? [_sendButton.layer setMasksToBounds:YES];? ? [_sendButton.layer setCornerRadius:4];? ? [_sendButton addTarget:selfaction:@selector(didSendButtonClicked:) forControlEvents:(UIControlEventTouchUpInside)];? ? [selfaddSubview:_sendButton];}- (void)didSendButtonClicked:(UIButton*)sender {if(self.buttonClicked) {self.buttonClicked(_draftTextField.text);? ? }? ? _draftTextField.text =@"";}- (NSString*)draftText {return_draftTextField.text;}/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

// Drawing code

}

*/@end

這個簡單的自定義view沒什么好說的,關(guān)鍵是他的.h文件

DialogBoxView.h

#importtypedefvoid(^ButtonClicked)(NSString* draftText);@interfaceDialogBoxView:UIView@property(nonatomic,copy) ButtonClicked buttonClicked;@end

這里用到一個block,當點擊按鈕時會調(diào)用這個block.

接下看看聊天界面的代碼吧.

#import"ChatViewController.h"#import"DialogBoxView.h"#import@interfaceChatViewController()@property(nonatomic,strong)UITableView*tableView;@property(nonatomic,strong)EMConversation *conversation;@property(nonatomic,strong)DialogBoxView *dialogBoxView;@end@implementationChatViewController-(void)loadView{? ? [superloadView];self.title = _name;self.navigationController.navigationBar.translucent =NO;? ? _tableView = [[UITableViewalloc]initWithFrame:CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height -50)];? ? _tableView.delegate =self;? ? _tableView.dataSource =self;? ? _tableView.tableFooterView = [[UIViewalloc]init];? ? [self.view addSubview:_tableView];}- (void)viewDidLoad {? ? [superviewDidLoad];? ? [_tableView setAllowsSelection:NO];? ? [selfregisterForKeyboardNotifications];? ? _dialogBoxView = [[DialogBoxView alloc]initWithFrame:CGRectMake(0,self.view.frame.size.height -114,self.view.frame.size.width,50)];? ? __weaktypeof(self) weakSelf =self;? ? _dialogBoxView.buttonClicked = ^(NSString* draftText){? ? ? ? [weakSelf sendMessageWithDraftText:draftText];? ? };? ? [self.view addSubview:_dialogBoxView];? ? [[EaseMob sharedInstance].chatManager addDelegate:selfdelegateQueue:dispatch_get_main_queue()];? ? [selfreloadChatRecords];}- (void)viewWillDisappear:(BOOL)animated {? ? [superviewWillDisappear:animated];// 移除通知中心[selfremoveForKeyboardNotifications];// 移除代理[[EaseMob sharedInstance].chatManager removeDelegate:self];}# pragma mark - Send Message/**

*? 使用草稿發(fā)送一條信息

*

*? @param draftText 草稿

*/- (void)sendMessageWithDraftText:(NSString*)draftText {? ? EMChatText * chatText = [[EMChatText alloc] initWithText:draftText];? ? EMTextMessageBody * body = [[EMTextMessageBody alloc] initWithChatObject:chatText];// 生成messageEMMessage * message = [[EMMessage alloc] initWithReceiver:self.name bodies:@[body]];? ? message.messageType = eMessageTypeChat;// 設置為單聊消息[[EaseMob sharedInstance].chatManager asyncSendMessage:message progress:nilprepare:^(EMMessage *message, EMError *error) {// 準備發(fā)送} onQueue:dispatch_get_main_queue() completion:^(EMMessage *message, EMError *error) {? ? ? ? [selfreloadChatRecords];// 發(fā)送完成} onQueue:dispatch_get_main_queue()];}# pragma mark - Receive Message/**

*? 當收到了一條消息時

*

*? @param message 消息構(gòu)造體

*/- (void)didReceiveMessage:(EMMessage *)message {? ? [selfreloadChatRecords];}# pragma mark - Reload Chat Records/**

*? 重新加載TableView上面顯示的聊天信息, 并移動到最后一行

*/- (void)reloadChatRecords {? ? _conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:self.name conversationType:eConversationTypeChat];? ? [_tableView reloadData];if([_conversation loadAllMessages].count >0) {? ? ? ? [_tableView scrollToRowAtIndexPath:[NSIndexPathindexPathForRow:[_conversation loadAllMessages].count -1inSection:0] atScrollPosition:(UITableViewScrollPositionBottom) animated:YES];? ? }}# pragma mark - Keyboard Method/**

*? 注冊通知中心

*/- (void)registerForKeyboardNotifications{// 使用NSNotificationCenter 注冊觀察當鍵盤要出現(xiàn)時[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(didKeyboardWillShow:) name:UIKeyboardWillShowNotificationobject:nil];// 使用NSNotificationCenter 注冊觀察當鍵盤要隱藏時[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(didKeyboardWillHide:) name:UIKeyboardWillHideNotificationobject:nil];}/**

*? 移除通知中心

*/- (void)removeForKeyboardNotifications {? ? [[NSNotificationCenterdefaultCenter] removeObserver:self];}/**

*? 鍵盤將要彈出

*

*? @param notification 通知

*/- (void)didKeyboardWillShow:(NSNotification*)notification {NSDictionary* info = [notification userInfo];CGSizekeyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue].size;NSLog(@"%f", keyboardSize.height);//輸入框位置動畫加載[selfbegainMoveUpAnimation:keyboardSize.height];}/**

*? 鍵盤將要隱藏

*

*? @param notification 通知

*/- (void)didKeyboardWillHide:(NSNotification*)notification {? ? [selfbegainMoveUpAnimation:0];}/**

*? 開始執(zhí)行鍵盤改變后對應視圖的變化

*

*? @param height 鍵盤的高度

*/- (void)begainMoveUpAnimation:(CGFloat)height {? ? [UIViewanimateWithDuration:0.3animations:^{? ? ? ? [_dialogBoxView setFrame:CGRectMake(0,self.view.frame.size.height - (height +40), _dialogBoxView.frame.size.width, _dialogBoxView.frame.size.height)];? ? }];? ? [_tableView layoutIfNeeded];if([_conversation loadAllMessages].count >1) {? ? ? ? [_tableView scrollToRowAtIndexPath:[NSIndexPathindexPathForRow:_conversation.loadAllMessages.count -1inSection:0] atScrollPosition:(UITableViewScrollPositionMiddle) animated:YES];? ? }}# pragma mark - Table View Data Source- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {return_conversation.loadAllMessages.count;}- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*identifier =@"cell";UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:identifier];if(!cell) {? ? ? ? cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:identifier];? ? }? ? EMMessage * message = _conversation.loadAllMessages[indexPath.row];? ? EMTextMessageBody * body = [message.messageBodies lastObject];//判斷發(fā)送的人是否是當前聊天的人,左邊是對面發(fā)過來的,右邊是自己發(fā)過去的if([message.to isEqualToString:self.name]) {? ? ? ? cell.detailTextLabel.text = body.text;? ? ? ? cell.detailTextLabel.textColor = [UIColorredColor];? ? ? ? cell.textLabel.text =@"";? ? ? ? cell.textLabel.textColor = [UIColorblueColor];? ? }else{? ? ? ? cell.detailTextLabel.text =@"";? ? ? ? cell.textLabel.text = body.text;? ? ? ? cell.detailTextLabel.textColor = [UIColorredColor];? ? ? ? cell.textLabel.textColor = [UIColorblueColor];? ? }returncell;}- (void)didReceiveMemoryWarning {? ? [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}@end

這里面也沒什么難點,也有注釋,相信大家能懂.

最后看看最后的成果圖吧.

成品圖

好了,今天就到這里,祝大家天天開心


如果覺得我的文章對您有用栓袖,請隨意贊賞。您的支持將鼓勵我繼續(xù)創(chuàng)作挣柬!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市栏豺,隨后出現(xiàn)的幾起案子钦幔,更是在濱河造成了極大的恐慌,老刑警劉巖乐纸,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衬廷,死亡現(xiàn)場離奇詭異,居然都是意外死亡汽绢,警方通過查閱死者的電腦和手機吗跋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宁昭,“玉大人跌宛,你說我怎么就攤上這事』蹋” “怎么了疆拘?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長斥扛。 經(jīng)常有香客問我入问,道長,這世上最難降的妖魔是什么稀颁? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任芬失,我火速辦了婚禮,結(jié)果婚禮上匾灶,老公的妹妹穿的比我還像新娘棱烂。我一直安慰自己,他們只是感情好阶女,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布颊糜。 她就那樣靜靜地躺著,像睡著了一般秃踩。 火紅的嫁衣襯著肌膚如雪衬鱼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天憔杨,我揣著相機與錄音鸟赫,去河邊找鬼。 笑死,一個胖子當著我的面吹牛抛蚤,可吹牛的內(nèi)容都是我干的台谢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼岁经,長吁一口氣:“原來是場噩夢啊……” “哼朋沮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缀壤,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤樊拓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诉位,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骑脱,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡菜枷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年苍糠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啤誊。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡岳瞭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚊锹,到底是詐尸還是另有隱情瞳筏,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布牡昆,位于F島的核電站姚炕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丢烘。R本人自食惡果不足惜柱宦,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望播瞳。 院中可真熱鬧掸刊,春花似錦、人聲如沸赢乓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牌芋。三九已至蚓炬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間躺屁,已是汗流浹背肯夏。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熄捍。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓烛恤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親余耽。 傳聞我的和親對象是個殘疾皇子缚柏,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容