(1)案例
(2)源代码于素材下载
http://pan.baidu.com/s/1bnpiBCz
(3)总结
——还是代码封装。控制器、视图、模型分别独立。里面还有很多代码可以独立出来整一个类。
——如果某一个值只有特定的几个数字,那么可以用枚举来定义,注意命名规范
typedef enum{ WPMessageTypeMe=0, WPMessageTypeOther=1 }WPMessageType;
——依然是计算一段文字所占据的宽和高
CGSize textMaxSize=CGSizeMake(200, MAXFLOAT); NSDictionary *[email protected]{NSFontAttributeName:[UIFont systemFontOfSize:14]}; CGSize textSize=[message.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attr1 context:nil].size;
——按钮的内边距,即把文字向内压缩。这里面textView是UIButton类。
textView.titleEdgeInsets=UIEdgeInsetsMake(20, 20, 20, 20);
——把一张小的图片做背景保持四周不变,拉伸中间,则用如下属性。UIEdgeInsets是拉伸的区域,一般取最中间的一个点。
UIImage *meBgNor=[UIImage imageNamed:@"chat_send_nor"]; UIEdgeInsets edge1=UIEdgeInsetsMake(28, 32, 28, 32); meBgNor=[meBgNor resizableImageWithCapInsets:edge1 resizingMode:UIImageResizingModeStretch]; [self.textView setBackgroundImage:meBgNor forState:UIControlStateNormal];
——去除cell的选中背景,以及去除cell之间的分割线
//去除选中背景 self.tableView.allowsSelection=NO; //去除分割线 self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone;
——输入框左边利用一个UIView设置留出一个空白
self.textView.leftView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 8, 0)]; self.textView.leftViewMode=UITextFieldViewModeAlways;
——通知的重要性,键盘的出现隐藏是系统的通知,系统会自动发送通知,我们需要增加一个通知监听者就是控制器本身,所以这里self。
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
——与此同时,增加一个通知监听的同时,在dealloc中销毁。
-(void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self]; }
——我们利用上述通知自带的信息,获取到键盘的移动位置,然后移动其他需要移动的控件。这里面通知的userInfo里面有很多信息,是一个字典。
——获取屏幕信息,用UIScreen mainScreen,如果是bounds,则可得到宽高。
——动画用UIView 的animateWith……
-(void)changeFrame:(NSNotification *)note{ self.view.superview.backgroundColor=[UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:0.9]; CGFloat duration=[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; CGFloat keyboardY=[note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y; CGFloat screenH=[UIScreen mainScreen].bounds.size.height; [UIView animateWithDuration:duration animations:^{ self.view.transform=CGAffineTransformMakeTranslation(0, keyboardY-screenH); }]; }
——隐藏键盘就是视图结束编辑。这个scrollView的代理方法tableView直接继承过来,可以直接用。
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ [self.view endEditing:YES]; }
——利用当前新数据与模型最后一个数据进行比较,如果相同,则隐藏这个控件。
WPMessageFrame *lastMsgFrame=[muArray lastObject]; if (msg.time==lastMsgFrame.message.time) { msg.hideTime=YES; }
if (message.hideTime==NO) { CGFloat timeX=0; CGFloat timeY=padding; CGFloat timeW=screenW; CGFloat timeH=40; _timeF=CGRectMake(timeX, timeY, timeW, timeH); }
——当按下键盘发送键时,可以使用textFieldDelegate的方法:获取文本框进行处理,这里直接创建了新的模型,并加入新的数目模型中,刷新tableView。
-(BOOL)textFieldShouldReturn:(UITextField *)textField{ }
——把tableView滚动到最下面,直接使用scrollView的代理方法。
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:self.msgFrames.count-1 inSection:0]; [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
——这里可以设置tableView的背景,也可以设置cell的背景。也可以设置window的背景,用view.window或者view.superView可以调出window。
——输入框可以去除边框,然后用背景填充,以保证在iOS6和iOS7的使用中APP风格一致
——returnKey可以设置成send(发送),默认是return(回车),还可以设置成其他选项。
——这里的布局主要由两块,上面是tableView,下面是一个UIView上面放了很多控件。这里面在storyBoard中不能直接往UIImageView中添加其他控件,只有在代码中实现。所以此处是用一个UIView,然后把UIImageView、UIButton和UITextField等添加进来。
——cell初始化的时候,往cell里面添加控件是添加在cell的contentView中的。
谨记,对于不同高度的自定义cell,需要两个模型,一个是数据模型,一个是frame模型,因为frame模型包含了数据模型,所以在初始化cell的视图中,只要拥有一个frame成员属性即可。