使用MVC模式
model(message.h)用来储存聊天信息的
@property (nonatomic,copy)NSString *content; //用来存储聊天信息
@property (nonatomic,copy)NSString *icon; //用户头像
@property (nonatomic,copy)NSString *time; //时间
@property (nonatomic,assign)BOOL isSelf;
view(messageCell.m)显示聊天信息
//外部传递数据时调用的方法(set方法)
- (void)setMessage:(Message *)message{
if (_message != message) {
[_message release];
_message = [message retain];
}
// 当此方法被调用时,说明数据已经传入
// [self layoutSubviews]; 错误,不要直接调用此方法
[self setNeedsLayout]; //通知系统,抽个空去调用一下layoutSubviews方法
}
//给子视图布局的方法
/*
当视图快要被渲染引擎渲染时,会调用此方法,渲染后视图就会出现在屏幕上
我们应该在此方法中做什么?
1.给子视图填充数据
2.布局子视图,设置子视图的frame
*/
- (void)layoutSubviews{
//一定要去调用父类的方法,不然分割线会出现问题
[super layoutSubviews];
UIImage *image = [UIImage imageNamed:_message.icon]; //用户头像
userimage.image = image;
//2.计算聊天信息所占用的空间大小
//此方法会显示警告,因为此方法在ios7中已不建议使用(但仍可以使用)
CGSize size = [_message.content sizeWithFont:[UIFont systemFontOfSize:16] constrainedToSize:CGSizeMake(220, 9999) lineBreakMode:NSLineBreakByWordWrapping];
//3.根据求得的大小设置lable的高度
_lable.text = _message.content;
//背景视图
UIImage *img1 = [UIImage imageNamed:@"chatfrom_bg_normal.png"]; //绿色背景
UIImage *img2 = [UIImage imageNamed:@"chatto_bg_normal.png"]; //白色 自己
UIImage *bgImg = _message.isSelf ?img2:img1;
bgImg = [bgImg stretchableImageWithLeftCapWidth:bgImg.size.width * .5 topCapHeight:bgImg.size.height * .7];
_bgImage.image = bgImg;
//布局子视图 需判断消息是否为自己发送
if (_message.isSelf) {
userimage.frame = CGRectMake(320 - 50, 10, 40, 40);
_bgImage.frame = CGRectMake(320-size.width-50-30, 10, size.width + 30, size.height + 30);
_lable.frame = CGRectMake(320-size.width-50-20, 20, size.width, size.height);
}else{
userimage.frame = CGRectMake(10, 10, 40, 40);
_bgImage.frame = CGRectMake(60, 10, size.width + 30, size.height + 30);
_lable.frame = CGRectMake(80, 20, size.width, size.height);
}
}
Controller(viewController.m)1.加载本地数据
2.创建视图
3.监听键盘弹出事件,当键盘弹出时,会收到UIKeyboardWillShowNotification通知
//UIKeyboardWillShowNotification通知名,定义在UIWindow类中
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showKeyBoard:) name:UIKeyboardWillShowNotification object:nil];
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//当视图出现的时候,显示最后一个单元格(最后一条消息)
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_data.count - 1 inSection:0];
[_tabelView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
实现代理方法
//返回单元格高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
//取到message对象,计算高度
Message *message = _data[indexPath.row];
CGSize size = [message.content sizeWithFont:[UIFont systemFontOfSize:16] constrainedToSize:CGSizeMake(220, 9999) lineBreakMode:NSLineBreakByWordWrapping];
return size.height + 40;
}
//键盘弹出后,会调用此通知方法
#pragma -mark notificationAction
- (void)showKeyBoard:(NSNotification *)notification{
// NSLog(@"%@",notification.userInfo);
NSDictionary *dic = notification.userInfo;
//取得键盘的frame
NSValue *value = [dic objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect rect = [value CGRectValue];
//得到键盘的高度
CGFloat height = rect.size.height;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.3];
_superView.transform = CGAffineTransformMakeTranslation(0, -height);
_tabelView.transform = CGAffineTransformMakeTranslation(0, -height);
[UIView commitAnimations];
}
//点击单元格时,缩回键盘
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// 将键盘缩回
[_inputView endEditing:YES]; //[_inputView resignFirstResponder];
//将视图的transform设为原始值
_superView.transform = CGAffineTransformIdentity;
_tabelView.transform = CGAffineTransformIdentity;
}
//单元格上面的删除,插入按钮被点击时,调用的方法
//此协议方法,实现后,左滑单元格会出现删除按钮
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//1.删除数组中的对象
[_data removeObjectAtIndex:indexPath.row];
// //2.刷新单元格
// [_tabelView reloadData];
//在tableView中删除一个单元格
[_tabelView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
#pragma -mark 发送消息
//send按钮被点击时,调用的方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
//1.获取用户输入的内容
NSString *text = textField.text;
//2.创建一个message对象
Message *message = [[Message alloc] init];
message.content = text;
message.icon = @"icon01.jpg";
message.isSelf = YES;
//将message对象放入数组中
[_data addObject:message];
// //刷新表视图
// [_tabelView reloadData];
//取得最后一个单元格的下标
NSInteger index = _data.count - 1;
NSIndexPath*indexPath = [NSIndexPath indexPathForRow:index inSection:0];
//在表视图的最后插入一个单元格
[_tabelView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
//滚动到最后一个单元格
[_tabelView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
//将输入框设为空
_inputView.text = nil;
return YES;
}