上篇博客介绍了如何使用UITableView实现类似QQ的好友界面布局。这篇讲述如何利用自定义单元格来实现聊天界面的布局。
借助单元格实现聊天布局难度不大,主要要解决的问题有两个:
1.自己和其他人说话头像和气泡图像在不同的位置。
找了些类似的例子,有根据不同情况设置不同的自定义类的。这里使用根据说话人的属性来设置不同的位置,在一个单一的单元格类中。
2.像微博等根据说话的内容长短对说话图片进行拉伸,以及单元格自适应高度。
实现步骤:
搭建界面
数据属性字典
读取数据
- (void)loadData { const NSString *RMsgKey = @"msg"; const NSString *RMineKey = @"ismine"; NSString *path = [[NSBundle mainBundle] pathForResource:@"messages" ofType:@"plist"]; NSArray *dataArray = [NSArray arrayWithContentsOfFile:path]; if (!dataArray) { MyLog(@"读取文件失败"); return; } _msgList = [NSMutableArray arrayWithCapacity:dataArray.count]; [dataArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) { Message *message = [[Message alloc] init]; message.msg = dict[RMsgKey]; message.mine = [dict[RMineKey] boolValue]; [_msgList addObject:message]; }]; }
将数据指定给Message类,存到一个数组中方便以后绑定到自定义单元格中
这次使用的是用NIB文件建的自定义,而非像前两篇博客使用手绘的方式。
awakeFromNib和layoutSubviews方法
- (void)awakeFromNib { _msgButton.titleLabel.numberOfLines = 0; _msgButton.titleLabel.font = [UIFont systemFontOfSize:RChatFontSize]; } - (void)layoutSubviews { [super layoutSubviews]; CGRect rect = _msgButton.frame; rect.size.height = self.bounds.size.height - 2*RMarginSize; _msgButton.frame = rect; }
然后是数据绑定方法,根据传入的数据,安排头像和会话按钮的位置
- (void)bindMessage:(Message *)message { UIImage *headerImage; UIImage *normalImage; UIImage *highlightedImage; CGRect iconRect = _headerView.frame; CGRect btnRect = _msgButton.frame; UIEdgeInsets insets; if (message.isMine) { headerImage = [UIImage imageNamed:@"me"]; normalImage = [UIImage imageNamed:@"mychat_normal"]; highlightedImage = [UIImage imageNamed:@"mychat_focused"]; iconRect.origin.x = RMarginSize; btnRect.origin.x = RBtnX; insets = UIEdgeInsetsMake(0, 20, 0, 30); } else { headerImage = [UIImage imageNamed:@"other"]; normalImage = [UIImage imageNamed:@"other_normal"]; highlightedImage = [UIImage imageNamed:@"other_focused"]; iconRect.origin.x = self.bounds.size.width - RMarginSize - RIconSide; btnRect.origin.x = self.bounds.size.width - iconRect.origin.x - RMarginSize; insets = UIEdgeInsetsMake(0, 30, 0, 30); } _headerView.frame = iconRect; _headerView.image = headerImage; //拉伸图片 normalImage = [normalImage stretchableImageWithLeftCapWidth:normalImage.size.width*0.5 topCapHeight:normalImage.size.height*0.6]; highlightedImage = [highlightedImage stretchableImageWithLeftCapWidth:highlightedImage.size.width*0.5 topCapHeight:highlightedImage.size.height*0.6]; [_msgButton setContentEdgeInsets:insets]; _msgButton.frame = btnRect; [_msgButton setBackgroundImage:normalImage forState:UIControlStateNormal]; [_msgButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; [_msgButton setTitle:message.msg forState:UIControlStateNormal]; }
关于上面拉伸图片的方法,在IOS6以后可以使用另一个方法,resizableImageWithCapInsets:<#(UIEdgeInsets)#> resizingMode:<#(UIImageResizingMode)#>
传入一个Edgeinsets和一个拉伸模式就可以对图片完成编辑。
下面在tableview的代理方法中设置自适应高度的行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { Message *msg = _msgList[indexPath.row]; UIFont *font = [UIFont systemFontOfSize:RChatFontSize]; CGFloat height = [msg.msg sizeWithFont:font constrainedToSize:CGSizeMake(150, 10000)].height; CGFloat lineHeight = [font lineHeight]; return RCellHeight + height - lineHeight; }
根据内容和字体设置合适的高度
最后绑定数据就可以完成显示了
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { HRChatCell *cell = [tableView dequeueReusableCellWithIdentifier:RCellIdentifier]; [cell bindMessage:_msgList[indexPath.row]]; return cell; }
完成效果
Demo源码:点击打开链接
以上为本篇博客全部内容,欢迎指正和交流。转载请注明出处~