zoukankan      html  css  js  c++  java
  • iOS边练边学--自定义非等高的cell

    一、使用xib或者storyboard自定义非等高的cell实现方式差不多,这里简单介绍一下通过xib文件实现的方法

    <1.1>创建一个继承自UITableViewCell的子类,比如ChaosWeiboCell

    <1.2>在模型中增加一个cellHeight属性,用来存放对应的cell的高度

    #import <UIKit/UIKit.h> // 这里修改成UIKit框架
    
    @interface ChaosWeibo : NSObject // 模型类
    /** 正文 */
    @property(nonatomic,strong) NSString *text;
    /** 头像 */
    @property(nonatomic,strong) NSString *icon;
    /** 配图 */
    @property(nonatomic,strong) NSString *picture;
    /** 用户名 */
    @property(nonatomic,strong) NSString *name;
    /** VIP */
    @property(nonatomic,assign,getter=isVIP) BOOL vip;
    // CGFloat在CG框架里面 NSString *在Foundation框架里面,UIKit框架包含了这两个框架
    /** cell的高度 */
    @property(nonatomic,assign) CGFloat cellHeight;
    
    // 提供一个将字典数据转换成模型数据的类方法
    + (instancetype)WeiboWithDict:(NSDictionary *)dict;
    @end
    

      

    <2>创建一个xib文件(文件名建议跟cell的类名一样),比如ChaosWeiboCell.xib

      <2.1>拖拽一个UITableViewCell出来

      <2.2>修改cell的class为ChaosWeiboCell

      <2.3>设置cell的重用标识

      <2.4>往cell中添加需要用到的子控件

    <3>在控制器中

      <3.1>利用registerNib...方法注册xib文件

      <3.2>利用重用标识找到cell(如果没有注册xib文件,就需要手动去加载xib文件)

      <3.3>给cell传递模型数据

      <3.4>在控制器中实现tableView:estimatedHeightForRowAtIndexPath:方法,返回一个估计高度,比如200

    // 给cell一个估计高度
    // 这个方法的意义在于:没有这个方法,程序的执行顺序是1、heightForRowAtIndexPath:方法得到cell的高度(高度不准确,有几个就获得几个的cell高度,消耗内存)2、然后cellForRowAtIndexPath:方法根据不准确的高度创建cell
    // 有了这个方法程序会根据这个大约的高度先去执行cellForRowAtIndexPath:方法,然后再执行heightForRowAtIndexPath:方法返回真正的cell高度
    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 200;
    }
    @end
    

      <3.5>在控制器中实现tableView:heightForRowAtIndexPath:方法,返回cell的真实高度(模型中的cellHeight属性)

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        ChaosWeibo *weibo = self.weiboArray[indexPath.row];
        return weibo.cellHeight;
    }
    

      

    <4>在ChaosWeiboCell中

      <4.1>将xib中的子控件连线到类扩展中

      <4.2>需要提供一个模型属性,重写set方法,在这个方法中设置模型属性到子控件上

        并且在set方法中调用[self layoutIfNeed]方法强制布局,然后计算出模型的cellHeight属性值

    - (void)setWeibo:(ChaosWeibo *)weibo
    {
        // 重写set方法不可少的代码
        _weibo = weibo;
        // 设置头像
        self.headView.image = [UIImage imageNamed:weibo.icon];
        // 设置昵称
        self.nameLabel.text = weibo.name;
        // 设置会员标志
        if (weibo.isVIP) {
            self.vipView.hidden = NO; // 重新将hidden属性设置为NO,因为cell是通过缓存池回收过来的,万一之前是hidden,这里没有这一句就不行了
            self.vipView.image = [UIImage imageNamed:@"vip"];
            self.nameLabel.textColor = [UIColor orangeColor];
        } else{
            self.vipView.hidden = YES;
            self.nameLabel.textColor = [UIColor whiteColor];
        }
        // 设置正文内容
        self.contentLabel.text = weibo.text;
        if (weibo.picture) {
            self.iconView.hidden = NO; // 同理
            self.iconView.image = [UIImage imageNamed:weibo.picture];
        } else {
            self.iconView.hidden = YES;
        }
        // 将绑定好数据的cell进行强制布局
        [self layoutIfNeeded];
        
        // 计算cell的高度
        if (self.iconView.hidden) { // 没有配图的情况
            weibo.cellHeight = CGRectGetMaxY(self.contentLabel.frame) + 10;
        } else { // 有配图的情况
            weibo.cellHeight = CGRectGetMaxY(self.iconView.frame) + 10;
        }
    }
    

      

      <4.3>也可以将创建获得cell的代码封装起来(比如cellWithTableView:方法)

    <5>需要注意的一点就是label的宽度问题,由于layoutIfNeed方法的原因,系统有时候算出的高度会于实际不符。因为系统算的高度是根据文字宽度算的。

    解决办法,通过调用一下方法:

    // 这个方法是自定义控件从xib文件初始化完后调用的方法,通过这个方法解决多行label算的高度不准的情况
    - (void)awakeFromNib
    {
        // 设置每一行label文字的最大宽度
        // 保证算出来的label的高度 跟 显示出来的效果一样
        self.contentLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
    }
    

      

  • 相关阅读:
    UE4蓝图第一天
    UE4材质常用快捷键
    第六天
    第五天
    第四天
    第三天
    第二天
    HDU 1495 非常可乐 (bfs,数论)
    HDU 变形课 (dfs)
    HDU 胜利大逃亡 (bfs)
  • 原文地址:https://www.cnblogs.com/gchlcc/p/5287535.html
Copyright © 2011-2022 走看看