zoukankan      html  css  js  c++  java
  • UITableView-hightForRow调用时刻-Cell行高计算和缓存Cell行高

    一、hightForRow调用时刻

     这个方法的特点:

     1.默认情况下

     1> 每次刷新表格时,有多少数据,这个方法就一次性调用多少次(比如有100条数据,每次reloadData时,这个方法就会一次性调用100次)

     2> 每当有cell进入屏幕范围内,就会调用一次这个方法

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    }

    二、Cell行高计算和缓存Cell行高

    用全局属性统计计算

    /** 用来缓存cell的高度(key:模型,value:cell的高度) */
    @property (nonatomic, strong) NSMutableDictionary *cellHeightDict;
    
    - (NSMutableDictionary *)cellHeightDict
    {
        if (!_cellHeightDict) {
            _cellHeightDict = [NSMutableDictionary dictionary];
        }
        return _cellHeightDict;
    }
    //Cell行高计算和缓存Cell行高
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        HKTopic *topic = self.topics[indexPath.row];
    
        NSString *key = topic.description;
    
        CGFloat cellHeight = [self.cellHeightDict[key] doubleValue];
        if (cellHeight == 0) { // 这个模型对应的cell高度还没有计算过
            // 文字的Y值
            cellHeight += 55;//顶部头像+margin
            
            // 文字的高度
            CGSize textMaxSize = CGSizeMake(SCREEN_WIDTH - 2 * HKMargin, MAXFLOAT);
            cellHeight += [topic.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]} context:nil].size.height + HKMargin;
            
            // 工具条
            cellHeight += 35 + HKMargin;
            
            // 存储高度
            self.cellHeightDict[key] = @(cellHeight);
            // [self.cellHeightDict setObject:@(cellHeight) forKey:key];
            HKLog(@"%zd %f", indexPath.row, cellHeight);
        }
        
        return cellHeight;
    }
    
    //最后在请求成功时,删除缓存
    // 清除之前计算的高度
    [self.cellHeightDict removeAllObjects];

    利用模型属性计算和缓存Cell行高

    /** 所有的帖子数据 */
    @property (nonatomic, strong) NSMutableArray<HKTopic *> *topics;
    
    //HKTopic数据模型类:
    //HKTopic.h 声明一个属性用来缓存Cell行高
    /* 额外增加的属性(并非服务器返回的属性,仅仅是为了提高开发效率) */
    /** 根据当前模型计算出来的cell高度 */
    @property (nonatomic, assign) CGFloat cellHeight;
    
    //HKTopic.m
    @implementation HKTopic
    - (CGFloat)cellHeight
    {
        // 如果已经计算过,就直接返回
        if (_cellHeight) return _cellHeight;
        
        JKFunc;
        
        // 文字的Y值
        _cellHeight += 55;
        
        // 文字的高度
        CGSize textMaxSize = CGSizeMake(SCREEN_WIDTH - 2 * HKMargin, MAXFLOAT);
        _cellHeight += [self.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]} context:nil].size.height + HKMargin;
        
        // 工具条
        _cellHeight += 35 + HKMargin;
        
        return _cellHeight;
    }
    
    @end
    
    //使用:
    /**
     这个方法的特点:
     1.默认情况下
     1> 每次刷新表格时,有多少数据,这个方法就一次性调用多少次(比如有100条数据,每次reloadData时,这个方法就会一次性调用100次)
     2> 每当有cell进入屏幕范围内,就会调用一次这个方法
     */
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        //    HKTopic *topic = self.topics[indexPath.row];
        //    return topic.cellHeight;
        return self.topics[indexPath.row].cellHeight;
    }

     三、estimatedRowHeight估算行高的作用

    // 设置cell的估算高度(每一行大约都是estimatedRowHeight)
    self.tableView.estimatedRowHeight = 200;
    
    // 所有cell的高度 -> contentSize.height -> 滚动条长度
    // 1000 * 20 -> contentSize.height -> 滚动条长度
    // contentSize.height -> 200 * 20 -> 16800
    /*
     使用estimatedRowHeight的优缺点
     1.优点
     1> 可以降低tableView:heightForRowAtIndexPath:方法的调用频率
     2> 将【计算cell高度的操作】延迟执行了(相当于cell高度的计算是懒加载的)
     
     2.缺点
     1> 滚动条长度不准确、不稳定,甚至有卡顿效果(如果不使用estimatedRowHeight,滚动条的长度就是准确的)
     */
    /**
     这个方法的特点:
     1.默认情况下(没有设置estimatedRowHeight的情况下)
     1> 每次刷新表格时,有多少数据,这个方法就一次性调用多少次(比如有100条数据,每次reloadData时,这个方法就会一次性调用100次)
     2> 每当有cell进入屏幕范围内,就会调用一次这个方法
     
     2.设置estimatedRowHeight的情况下
     1> 用到了(显示了)哪个cell,才会调用这个方法计算那个cell的高度(方法调用频率降低了)
     */
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        //    HKTopic *topic = self.topics[indexPath.row];
        //    return topic.cellHeight;
        return self.topics[indexPath.row].cellHeight;
    }
    -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return self.topics[indexPath.row].cellHeight;
    }
  • 相关阅读:
    LeetCode
    LeetCode
    static,final,包,访问修饰符,内部类
    抽象类和抽象方法接口和多态
    抽象类和抽象方法
    memcache的使用、版本使用和相关配置
    apache mysql无法启动解决办法
    thinkphp实现文件的下载
    xampp 出现403 无法访问问题(已解决)
    Thinkphp使用phpexcel导入文件并写入数据库
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/CellHeightCache.html
Copyright © 2011-2022 走看看