M
V
C
#import "ViewController.h"#import "ChatCell.h"#import "ChatModel.h"@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>{ UITableView *_tableView; NSMutableArray *_dataArray; UIView *_chatView; UITextField *_textField;}@end@implementation ViewController- (BOOL)prefersStatusBarHidden{ return YES;}- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _dataArray = [[NSMutableArray alloc] init]; //屏幕宽高 。 CGSize winSize = self.view.frame.size; _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, winSize.width, winSize.height - 40)]; _tableView.delegate = self; _tableView.dataSource = self; _tableView.userInteractionEnabled = YES; // 分隔线d _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [self.view addSubview:_tableView]; _chatView = [[UIView alloc] initWithFrame:CGRectMake(0, winSize.height-40, winSize.width, 40)]; _chatView.backgroundColor = [UIColor grayColor]; _textField.userInteractionEnabled = YES; [self.view addSubview:_chatView]; _textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 5, winSize.width-60, 30)]; _textField.borderStyle = UITextBorderStyleRoundedRect; [_chatView addSubview:_textField]; UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = CGRectMake(winSize.width-40, 5, 30, 30); [button setTitle:@"发送" forState:UIControlStateNormal]; [button addTarget:self action:@selector(sendText) forControlEvents:UIControlEventTouchUpInside]; [_chatView addSubview:button]; //监听键盘出现 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; //监听键盘消失 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; }- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [_textField resignFirstResponder];}//键盘出现- (void)keyboardWillShow:(NSNotification *)noti{ //键盘高 CGSize size = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size; //屏幕宽高 CGSize winSize = self.view.frame.size; //tableview的大小 _tableView.frame = CGRectMake(0, 0, winSize.width, winSize.height - 40 - size.height); //chatview的位置 _chatView.frame = CGRectMake(0, winSize.height - 40 - size.height, winSize.width, 40);}//键盘消失- (void)keyboardWillHide:(NSNotification *)noti{ //屏幕宽高 CGSize winSize = self.view.frame.size; //tableview的大小 _tableView.frame = CGRectMake(0, 0, winSize.width, winSize.height - 40); //chatview的位置 _chatView.frame = CGRectMake(0, winSize.height - 40, winSize.width, 40);}//发送文本- (void)sendText{ ChatModel *chatModel = [[ChatModel alloc] init]; chatModel.content = _textField.text; chatModel.isSelf = YES; _textField.text = @""; [_dataArray addObject:chatModel]; //添加一行 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0]; [_tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; //滚动到最后一行 [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(autoSpeak) userInfo:nil repeats:NO];}- (void)autoSpeak{ NSArray *array = @[@"好的",@"没问题",@"一边去",@"忙呢",@"去死。"]; ChatModel *chatModel = [[ChatModel alloc] init]; chatModel.content = array[arc4random()%array.count]; chatModel.isSelf = NO; [_dataArray addObject:chatModel]; //添加一行 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0]; [_tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; //滚动到最后一行 [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return _dataArray.count;}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ ChatModel *chatModel = _dataArray[indexPath.row]; CGSize size = [chatModel.content boundingRectWithSize:CGSizeMake(250, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15.0]} context:nil].size; return size.height + 25;}- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ ChatCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ID"]; if (cell == nil) { cell = [[[NSBundle mainBundle] loadNibNamed:@"ChatCell" owner:self options:nil]firstObject]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } ChatModel *chatModel = _dataArray[indexPath.row]; //计算文本所占大小 CGSize size = [chatModel.content boundingRectWithSize:CGSizeMake(250, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15.0]} context:nil].size; CGSize winSize = [[UIScreen mainScreen] bounds].size; if (chatModel.isSelf) { //自己发的 cell.rightBubble.hidden = NO; cell.leftBubble.hidden = YES; //显示文本 cell.rightLabel.text = chatModel.content; //重新计算label和气泡的大小 //右边 cell.rightLabel.frame = CGRectMake(10, 5, size.width, size.height); cell.rightBubble.frame = CGRectMake(winSize.width - 30 - size.width, 5,size.width + 20, size.height + 20); } else { //接受到的 cell.rightBubble.hidden = YES; cell.leftBubble.hidden = NO; //显示文本 cell.leftLabel.text = chatModel.content; //重新计算label和气泡的大小 cell.leftLabel.frame = CGRectMake(15, 5, size.width, size.height); cell.leftBubble.frame = CGRectMake(10, 5, size.width + 20, size.height + 20); } return cell;}适应TCP可以做一个及时气泡聊天#import "ViewController.h"#import "AsyncSocket.h"@interface ViewController ()<AsyncSocketDelegate>{ IBOutlet UITextField *_ipField; IBOutlet UITextField *_sendField; IBOutlet UITextView *_textView; NSMutableArray *_mArray; //客户端 AsyncSocket *_clientSocket; //服务端 AsyncSocket *_serverSocket;}- (IBAction)conToHost:(id)sender;- (IBAction)sendText:(id)sender;@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _mArray = [[NSMutableArray alloc] init]; //客户端 _clientSocket = [[AsyncSocket alloc] initWithDelegate:self]; //服务端 _serverSocket = [[AsyncSocket alloc] initWithDelegate:self]; //监听有没有客户端连接 [_serverSocket acceptOnPort:5678 error:nil];}//监听到客户端已连接,调下面方法时,三次握手已完成,sock只负责监听(_serverSocket),连接是newSocket- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket{ [_mArray addObject:newSocket]; //监听客户端发送消息 [newSocket readDataWithTimeout:-1 tag:0];}//当监听到客户端发送了消息- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{ NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if (_textView.text.length >= 100) { _textView.text = @""; } //消息显示到textview上,sock.connectedHost是客户端的地址 _textView.text = [NSString stringWithFormat:@"%@%@:%@\n",_textView.text,sock.connectedHost,str]; //继续监听客户端发送消息 [sock readDataWithTimeout:-1 tag:0];}//连接- (void)conToHost:(id)sender{ //如果已经连接,先断开 if (_clientSocket.isConnected) { [_clientSocket disconnect]; } [_clientSocket connectToHost:_ipField.text onPort:5678 withTimeout:30 error:nil];}//连接成功- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{ NSLog(@"连接成功");}//发送- (void)sendText:(id)sender{ NSData *data = [_sendField.text dataUsingEncoding:NSUTF8StringEncoding]; _sendField.text = @""; [_clientSocket writeData:data withTimeout:30 tag:0];}//发送成功- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag{ NSLog(@"发送成功");}