使用Custom UITableViewCells改进ViewController加载速度(破纪录) [英] improving ViewController load speed with Custom UITableViewCells (a broken record)

查看:74
本文介绍了使用Custom UITableViewCells改进ViewController加载速度(破纪录)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有UITableView的UIViewController加载得非常慢(可能是糖蜜慢)我可以告诉它是由于在ViewController拥有的分组UITableview中为UITableViewCells设置自定义背景图像。

I have a UIViewController with a UITableView that is loading incredibly slow (slow as molasses, perhaps) I can tell it's due to setting custom background images for UITableViewCells in my grouped UITableview owned by the ViewController.

我认为我跟随其他SO问题中提到的建议:
提高iPhone UITableView滚动性能的技巧

I think I'm following as much as the recommendation noted in this other SO question: Tricks for improving iPhone UITableView scrolling performance

I我也遵循了这篇文章,以确保我没有做一些愚蠢的事情:
Cocoa With Love自定义UITableView绘图

I've also followed this article to make sure I'm not doing something stupid: Cocoa With Love Custom UITableView Drawing

一旦我不调用背景样式代码,性能就会提高。

As soon as I don't invoke background styling code, the performance improves.

根据建议,我正在执行以下所有步骤:

Following the suggestions, I'm doing all these steps:



  • 由于设计的方式,我有2种不同的细胞变异,并且不能具有统一的行高。无论细胞变化如何,行背景总是3个图像中的1个并且基于行索引。 0:top_row_image,n-1:bottom_row_image,所有其他:middle_row_image

  • 我在ViewController的viewDidLoad中加载用于背景的图像。

  • 我没有任何drawRect代码,因为我让单元格中的UITextField处理

  • Cell的图层设置为不透明

  • Cell正在重复使用标识符

  • 不从NIB文件加载单元格

  • Because of the way the designs are, I have 2 different cell variations and cannot have uniform row height. Regardless of the cell variation, the row background is always 1 of 3 images and is based on the row index. 0: top_row_image, n-1: bottom_row_image, all others: middle_row_image
  • I'm loading the images used for the background in my ViewController's viewDidLoad.
  • I don't have any drawRect code as I'm letting the UITextField inside the cell handle that
  • Cell's layer is set to opaque
  • Cell identifiers are being reused
  • Not loading the cell from a NIB file

基本上,我想根据表格的行类型,为每个表格的部分行设置不同的顶部,中间和底部行背景图像。任何人都可以建议在UITableView上使用自定义背景的更好方法吗?

Basically, I want to style the each of the table's section's rows with different top, middle and bottom row background images, depending on which type of row type it is. Can anyone suggest a better way to have custom backgrounds on a UITableView?

这是我的代码:

ViewController:
@property (nonatomic, weak) IBOutlet                            *tableview;
@property (nonatomic, strong, readwrite) UIImage                *topRowImage;
@property (nonatomic, strong, readwrite) UIImage                *middleRowImage;
@property (nonatomic, strong, readwrite) UIImage                *bottomRowImage;

@synthesize tableview = _tableview;    
@synthesize topRowImage = _topRowImage;         
@synthesize middleRowImage = _middleRowImage;
@synthesize bottomRowImage = _bottomRowImage;

// Load the images that will be used for the cell background ahead of time
- (void)viewDidLoad
{
    [super viewDidLoad];        

    // All of the images are 60x20 but my cells are 300x44 or 300x56
    UIEdgeInsets edgeInsets = UIEdgeInsetsMake(2, 4, 2, 4);        
    self.topRowImage = [[UIImage imageNamed:@"top_row.png"] resizableImageWithCapInsets:edgeInsets];        

    UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0, 4, 0, 4);
    self.middleRowImage = [[UIImage imageNamed:@"middle_row.png"] resizableImageWithCapInsets:edgeInsets];            

    edgeInsets = UIEdgeInsetsMake(2, 4, 2, 4);
    self.bottomRowImage = [[UIImage imageNamed:@"bottom_row.png"] resizableImageWithCapInsets:edgeInsets];    
}

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellId = [self getCellIdAt:indexPath];

    BaseCustomTableViewCell *cell = (BaseCustomTableViewCell *)[aTableView dequeueReusableCellWithIdentifier:cellId];

    if (cell == nil) 
    {
        if ([cellId isEqualToString:@"CellId1"])
        {
           cell = [[CustomTableViewCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];     
        }
        else
        { 
           cell = [[CustomTableViewCell2 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];     
        }
    }

    // the following line seems to be the bottleneck
    [self styleBackground:cell indexPath:indexPath totalRows:totalRows];

    [cell configureData:myRowData];
}

- (void)styleCellBackground:(BaseCustomTableViewCell *)cell 
                  indexPath:(NSIndexPath *)indexPath
                  totalRows:(NSInteger)totalRows
{
    UIImage *backgroundImage = nil;    

    if (indexPath.row == 0)
    {
        // Top row of this section        
        backgroundImage = self.topRowImage; // ivar loaded during 'viewDidLoad'
    }
    else if (indexPath.row == totalRows - 1)
    {
        // Bottom row of this section        
        backgroundImage = self.bottomRowImage;
    }
    else {
        // Middle row of this section        
        backgroundImage = self.middleRowImage;
    }

    [cell updateRowBackground:backgroundImage];
}

@implementation CustomTableViewCell

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {        
        // Create my text field
        _textField = [[UITextField alloc] initWithFrame:CGRectZero];        
        _textField.backgroundColor          = [UIColor whiteColor];    

        self.backgroundColor                = [UIColor whiteColor];            
        self.contentView.backgroundColor    = [UIColor whiteColor];

        self.backgroundView = [[UIImageView alloc] init];        

        // not sure which of these should be set to opaque to ensure to meet criteria #4
        // 4. Make your UITableViewCell's layer opaque (same goes for the content view if you have one)
        self.backgroundView.opaque = YES;
        self.layer.opaque = YES;
        self.opaque = YES;        
        self.contentView.opaque = YES;        

        [self.contentView addSubview:_textField];
    }
}

- (void)layoutSubviews
{    
    CGRect textFieldFrame = CGRectMake(10, 2, 278, 40);
    self.textField.frame = textFieldFrame;

    [super layoutSubviews];
}

- (void)updateRowBackground:(UIImage *)rowBackground
{
    ((UIImageView *)self.backgroundView).image = rowBackground;        
}


推荐答案

我想你会看到如果您在每次调用时停止将每个单元格的背景图像切换为 cellForRowAtIndexPath ,则会获得显着的性能提升。

I think you'll see a significant performance gain if you stop switching the background image of every single cell on every call to cellForRowAtIndexPath.

它听起来你有三种细胞(顶部,中间和底部)。您可以停止重复使用它们,因此必须在每次使用时重置其背景图像。

It sounds like you have three kinds of cells ("top", "middle", and "bottom"). You can stop reusing them interchangeably and therefore having to reset their background images on every use.

相反,您可以使用不同的标识符初始化表格单元格的实例,具体取决于它们在桌子。这样,您将创建一个具有顶部标识符的单个单元格,一个具有底部标识符的单个单元格,以及具有中间标识符的许多单元格。然后,您只能在初始化单元格时设置其背景图像。只要您尝试重复使用具有适当标识符的单元格,您就不再需要每次都更改其背景图像。

Instead you can init instances of your table cell with different identifiers depending on their position in the table. That way you'll create a single cell with a "top" identifier, a single cell with a "bottom" identifier, and many cells with a "middle" identifier. You can then set their background image only when you initialize the cell. As long as you attempt to reuse a cell with an appropriate identifier you'll no longer need to change their background images every time.

这篇关于使用Custom UITableViewCells改进ViewController加载速度(破纪录)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆