美文网首页
iOS UITableViewCell 性能优化

iOS UITableViewCell 性能优化

作者: 隔壁陈嘉敏 | 来源:发表于2018-03-31 16:20 被阅读38次

    每一个有使用列表 App 都会用到 UITableView 或 UICollectionView,这就意味着也会用到 UITableViewCell 或 UICollectionViewCell。因为 UITableView 和 UICollectionView 不是静止不动的,在与用户交互过程中,需要通过不断地滚动来更新数据,而更新数据的展示就需要通过更新 UITableViewCell 和 UICollectionViewCell 的展示数据。

    以 UITableViewCell 为例,UITableViewCell 自带一个UIImageView 和两个 UILabel,但是这些控件的布局是由 UITableViewCellStyle 决定的,使用 setFrame: 也是没有效果。显然只有这三个控件和固定的几种样式,是满足不了大多数产品需求和美工设计的。这个时候,我们就会想到使用复合视图的方式来实现设计需求,即在 UITableViewCell 的基础上添加新的视图控件。

    然而,使用复合视图并不是一个好的方案,这就意味着将增加了视图层次结构的嵌套层次。虽然视图层次的多层嵌套是难免的,也是必要的,但是深层次的嵌套结构势必影响性能。因为当父视图更新布局时,就会触发 setNeedsLayout: 方法,而当这个方法被触发时也会触发 layoutSubviews: 方法去更新所有子视图的布局。所以我们应当避免在视图层次结构中多层嵌套,尽量保持扁平化。

    那么问题来了,不用复合视图要怎么解决复杂的列表设计呢?
    那就在一个视图控件上实现要多个视图控件才能做到的事情。我们使用重写 UIView 的 drawRect: 方法来自定义渲染元素,将需要显示的图片和文字直接绘制到一张视图上。

    自定义 UITableViewCell 的头文件 ImproveTableViewCell.h :

    /**
     绘制 cell
     */
    @interface ImproveTableViewCell : UITableViewCell
    
    /**
     标题
     */
    @property (nonatomic, copy) NSString *strTitle;
    
    /**
     图片组
     */
    @property (nonatomic, copy) NSArray<NSString *> *arrImage;
    
    /**
     日期
     */
    @property (nonatomic, copy) NSString *strDate;
    
    @end
    

    实现文件 ImproveTableViewCell.m :

    
    @implementation ImproveTableViewCell
    
    
    /**
     重写视图方法绘制
    
     @param rect 坐标大小
     */
    - (void)drawRect:(CGRect)rect {
     
        // 屏幕宽
        CGFloat fScreenWidth = [[UIScreen mainScreen] bounds].size.width;
        // 文本属性
        NSDictionary *dicAttribute;
        
        // 标题
        dicAttribute = @{NSFontAttributeName: [UIFont systemFontOfSize:14], NSForegroundColorAttributeName: [UIColor colorWithWhite:0.2 alpha:1.0]};
        [self.strTitle drawInRect:CGRectMake(10, 10, fScreenWidth - 20, 20) withAttributes:dicAttribute];
        
        // 图片组
        // 图片宽
        CGFloat fImageWidth = (fScreenWidth - 40)/3;
        for (int i = 0; i < 3; i++) {
            
            UIImage *imgPicture = [UIImage imageNamed:self.arrImage[i]];
            [imgPicture drawInRect:CGRectMake(10 + i * (fImageWidth + 10), 40, fImageWidth, fImageWidth * 3/4)];
        }
        
        // 日期
        dicAttribute = @{NSFontAttributeName: [UIFont systemFontOfSize:13], NSForegroundColorAttributeName: [UIColor colorWithWhite:0.6 alpha:1.0]};
        [self.strDate drawInRect:CGRectMake(10, 45 + fImageWidth * 3/4, fScreenWidth - 20, 20) withAttributes:dicAttribute];
        
        // 分割线
        [[UIColor colorWithWhite:0.9 alpha:1.0] set];
        UIRectFill(CGRectMake(0, 65 + fImageWidth * 3/4, fScreenWidth, 5));
    }
    
    @end
    

    UITableViewDelegate 和 UITableViewDataSource 的方法实现:

    - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
        
        ImproveTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:gDrawID];
        if (cell == nil) {
            
            cell = [[ImproveTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:gDrawID];
            
        }
        cell.strTitle = indexPath.row%2 ? @"蜡笔小新--lol船长" : @"葛力姆乔·贾卡杰克";
        cell.arrImage = indexPath.row%2 ? @[@"test1", @"test2", @"test1"] : @[@"test2", @"test1", @"test2"];
        cell.strDate = indexPath.row%2 ? @"2018-03-30 大傻逼" : @"2018-03-31 小傻逼";
            
        // 更新渲染
        [cell setNeedsDisplay];
        
        return cell;
    }
    
    - (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
        
        return 100;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        
        return ([[UIScreen mainScreen] bounds].size.width - 40)/4 + 70;
    }
    

    结果截图:


    结果截图@2x.png

    参考资料:《高性能 iOS 应用开发》

    相关文章

      网友评论

          本文标题:iOS UITableViewCell 性能优化

          本文链接:https://www.haomeiwen.com/subject/kfogcftx.html