//
// ViewController.m
// Socket1
//
// Created by 阿仁欧巴 on 16/5/7.
// Copyright © 2016年 aren. All rights reserved.
//
#import "ViewController.h"
#import "GCDAsyncSocket.h"
@interface ViewController () < UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate, GCDAsyncSocketDelegate>
{
GCDAsyncSocket *_socket; //成员变量
}
//@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomViewConstraint;
@property (weak, nonatomic) IBOutlet UIView *commentView;//底部的文本框父视图,通过键盘的出现与否改变它的frame
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *chatMsgs; //聊天消息数组
@end
@implementation ViewController
- (NSMutableArray *)chatMsgs
{
if (!_chatMsgs) {
_chatMsgs = [NSMutableArray array];
}
return _chatMsgs;
}
//连接服务器的按钮
- (IBAction)connect:(id)sender
{
//和服务器建立连接的步骤
NSString *host = @"127.0.0.1";
int port = 8080;
//创建一个socket对象 代理方法都会在子线程调用,在刷新UI时就要回到主线程
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
//链接服务器
NSError *error = nil;
#pragma mark ---使用GCDAsyncSocket就不用将C语言形式的输入输出流转换成OC对象了,因为已经帮我们封装好了---
[_socket connectToHost:host onPort:port error:&error];
if (error) {
NSLog(@"%@",error);
}
}
//登录按钮
- (IBAction)login:(id)sender {
//登录的指令
NSString *logStr = @"iam:阿仁";
NSData *data = [logStr dataUsingEncoding:NSUTF8StringEncoding];
//发送登录消息数据给服务器 登录的时候
[_socket writeData:data withTimeout:-1 tag:101];
}
#pragma mark --当数据成功发送到服务器, 才会执行下面的代理方法---
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
NSLog(@"数据成功发送到服务器");
//,自己调用一下读取数据的方法, 发送数据成功后,接着_socket才会执行下面的方法,
[_socket readDataWithTimeout:-1 tag:tag];
}
#pragma mark ---GCDAsyncSocketDelegate---
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
NSLog(@"链接主机成功");
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
if (err) {
NSLog(@"和主机断开链接");
}
}
#pragma mark ---服务器有数据, 就会执行这个方法---
//接收到数据
//点击键盘发送按钮,发送消息数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
//将接收到的数据转换成字符串形式,在tableView中展示出来
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",dataString);
//刷新表格
if (tag == 102) {
[self reloadDataWithText:dataString];
NSLog(@"发送的是键盘输入的消息数据");
} else if (tag == 101) {
NSLog(@"发送的是登录数据");
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(@"%@",textField.text);
NSString *msStr = textField.text;
NSData *data = [msStr dataUsingEncoding:NSUTF8StringEncoding];
//刷新表格 并且让表格自动滚动到最后一行的位置
[self reloadDataWithText:textField.text];
//_socket发送数据
[_socket writeData:data withTimeout:-1 tag:102];
//发送完成清空输入框
textField.text = nil;
return YES;
}
- (void)reloadDataWithText:(NSString *)text
{
//将发送的消息存入本地数组中,作为数据源 展示在tableView上
[self.chatMsgs addObject:text];
#pragma mark ---回到主线程刷新UI,因为在刚开始创建Socket设置代理的时候代理队列是全局并发队列,在子线程中执行---
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
//获取最后一行的indexPath
NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.chatMsgs.count - 1 inSection:0];
//tableView 自动滚动到最后一行
[self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
#pragma mark --- 将要拖动时,键盘消失---
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self.view endEditing:YES];
}
- (void)viewDidLoad {
[super viewDidLoad];
//监听键盘将要出现时
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChang:) name:UIKeyboardWillChangeFrameNotification object:nil];
//监听键盘将要隐藏时
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view insertSubview:_tableView atIndex:0];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)keyboardWillChang:(NSNotification *)noti
{
NSLog(@"%@",noti.userInfo);
//键盘结束的y值
CGRect kbEndFrame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
[UIView animateWithDuration:[noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
self.commentView.transform = CGAffineTransformMakeTranslation(0, -kbEndFrame.size.height);
}];
}
- (void)keyboardWillHidden:(NSNotification *)noti
{
//键盘结束的y值
[UIView animateWithDuration:[noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
//让文本框视图变回初始的状态
self.commentView.transform = CGAffineTransformIdentity;
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.chatMsgs.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
cell.textLabel.text = self.chatMsgs[indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end