• IOS详解TableView——对话聊天布局的实现



    上篇博客介绍了如何使用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源码:点击打开链接



    以上为本篇博客全部内容,欢迎指正和交流。转载请注明出处~


  • 相关阅读:
    学习Extjs4 (21) 简单窗口
    C#启动外部程序的几种方法以及等待外部程序关闭的方法
    linux驱动学习(3)同步、信号量和自旋锁
    andoird webiew使用有道辞典实例
    Linux程序设计——用getopt处理命令行参数(转)
    git,github在windows上的搭建
    sparc芯片验证
    睡了一下午
    UNIX/Linux里统计文件里某个字符出现的次数(转)
    linux和单片机的串口通信
  • 原文地址:https://www.cnblogs.com/james1207/p/3310451.html
Copyright © 2020-2023  润新知