zoukankan      html  css  js  c++  java
  • 记一次简单的UITableView卡顿优化

    先说需求,要做一个类似这种的列表

    标签控件直接用的第三方

    YZTagList

     不知道的可以去搜一下,当这不重要。

    重要的是这个控件加载数据的时候非常影响列表滑动效果,造成卡顿,尤其是列表行数如果更多的话,

    这也不是要说的重点,自己写的控件也不一定就不耗性能,所以记一下我这次的处理方法。

    先看一下cell代码:

     1 @interface PreferTableViewCell ()
     2 @property (nonatomic, weak) UILabel *titleLabel;
     3 @property (nonatomic, strong) YZTagList *tagList;
     4 @end
     5 
     6 @implementation PreferTableViewCell
     7 
     8 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
     9     if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
    10         [self setupUI];
    11     }
    12     return self;
    13 }
    14 - (void)setupUI {
    15     UIView *lineView = [[UIView alloc] init];
    16     lineView.backgroundColor = [UIColor colorWithRed:246/255.0 green:247/255.0 blue:248/255.0 alpha:1.0];
    17     [self.contentView addSubview:lineView];
    18     [lineView makeConstraints:^(MASConstraintMaker *make) {
    19         make.left.equalTo(self);
    20         make.right.equalTo(self);
    21         make.height.equalTo(10);
    22         make.top.equalTo(self);
    23     }];
    24     
    25     UILabel *titleLabel = [[UILabel alloc] init];
    26     titleLabel.textColor = [UIColor blackColor];
    27     titleLabel.font = [UIFont systemFontOfSize:15];
    28     [self.contentView addSubview:titleLabel];
    29     self.titleLabel = titleLabel;
    30     [titleLabel makeConstraints:^(MASConstraintMaker *make) {
    31         make.left.equalTo(self).offset(15);
    32         make.top.equalTo(lineView.bottom).offset(10);
    33     }];
    34     
    35     YZTagList *tagList = [[YZTagList alloc] init];
    36     tagList.isSort = NO;
    37     tagList.backgroundColor = [UIColor whiteColor];
    38     // 高度可以设置为0,会自动跟随标题计算
    39     tagList.frame = CGRectMake(15, 50, SCREEN_WIDTH - 30, 0);
    40     // 设置标签背景色
    41     tagList.tagBackgroundColor = [UIColor colorWithRed:246/255.0 green:247/255.0 blue:248/255.0 alpha:1.0];
    42     // 设置标签颜色
    43     tagList.tagColor = [UIColor colorWithHex:@"#303030"];
    44     
    45     tagList.tagFont = [UIFont systemFontOfSize:13];
    46     tagList.tagCornerRadius = 4;
    47     tagList.clickTagBlock = ^(UIButton *btn){
    48         btn.selected = !btn.isSelected;
    49         if (btn.isSelected) {
    50             [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    51             [btn setBackgroundColor:[UIColor colorWithHex:@"#7676FD"]];
    52         } else {
    53             [btn setTitleColor:[UIColor colorWithHex:@"#303030"] forState:UIControlStateNormal];
    54             [btn setBackgroundColor:[UIColor colorWithRed:246/255.0 green:247/255.0 blue:248/255.0 alpha:1.0]];
    55         }
    56     };
    57     [self.contentView addSubview:tagList];
    58     
    59     self.tagList = tagList;
    60 }
    61 - (void)setTitle:(NSString *)title {
    62     _title = title;
    63     self.titleLabel.text = title;
    64 }
    65 - (void)setTags:(NSArray *)tags {
    66     _tags = tags;
    67     
    68     if (self.tagList.tagArray.count > 0) {
    69         return;
    70     }
    71     [self.tagList addTags:tags];
    72 }
    73 + (CGFloat)calcHeight:(NSArray *)tags {
    74     YZTagList *tagList = [[YZTagList alloc] init];
    75     tagList.frame = CGRectMake(15, 50, SCREEN_WIDTH - 30, 0);
    76     tagList.tagFont = [UIFont systemFontOfSize:13];
    77     tagList.tagCornerRadius = 4;
    78     [tagList addTags:tags];
    79     return tagList.tagListH + 45 + 21;
    80 }
    81 @end


    然后是VC代码:

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return self.tags.count;
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSString *ID = [NSString stringWithFormat:@"%ld%ld",indexPath.section,indexPath.row];
        PreferTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
        if (!cell) {
            cell = [[PreferTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        cell.title = @"11111111"; 
        cell.tags = self.tags[indexPath.row];
        return cell;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        CGFloat height = 0;
        height = [[self.cellheightCache objectForKey:[NSString stringWithFormat:@"%ld%ld",indexPath.section,indexPath.row]] floatValue];
        if (height == 0) {
            height = [PreferTableViewCell calcHeight:self.tags[indexPath.row]];
            [self.cellheightCache setObject:@(height) forKey:[NSString stringWithFormat:@"%ld%ld",indexPath.section,indexPath.row]];
        }
        return height;
    }

    前提:tags是一个二维数组。

    1.首先没有使用cell重用机制,避免多次

    [self.tagList addTags:tags];

    影响滑动效果,反正标签占用内存微乎其微。

    然后:

    if (self.tagList.tagArray.count > 0) { return; }

    一样的目的。到这里每个cell赋值只会发生一次。并且cell视图均缓存在内存中了。

    2.然后是计算行高,计算行高需要用到一个类方法,代码写的很清楚了,直接用

    YZTagList

    算出来并返回。然后用一个可变字典将高度缓存起来,这样保证高度也只会计算一次。

    3.当然了,我的标题顺序并不是代码运行顺序。

  • 相关阅读:
    (4) 编译 Android-5.0 源码
    (3) 下载 Android-5.0 源码
    (2) 搭建 Android 系统开发环境
    npm 安装 --save-dev 与 --save的使用与区别
    一点目标
    AcWing 875. 快速幂
    Codeforces Round #604 (Div. 2)
    2019年安徽大学ACM/ICPC实验室新生赛(公开赛)D 不定方程
    C语言黑与白问题
    AcWing 92. 递归实现指数型枚举
  • 原文地址:https://www.cnblogs.com/alan12138/p/10238909.html
Copyright © 2011-2022 走看看