ios - 通过自定义UITableViewCells提高ViewController的加载速度(记录已损坏)

标签 ios ios5 uitableview

我有一个带有UITableView的UIViewController,它的加载速度非常慢(也许是糖蜜般缓慢),我可以说这是由于在ViewController拥有的分组的UITableview中为UITableViewCells设置了自定义背景图像。

我认为我正在遵循这个其他SO问题中提到的建议:
Tricks for improving iPhone UITableView scrolling performance

我还关注了这篇文章,以确保我没有做蠢事:
Cocoa With Love Custom UITableView Drawing

只要不调用后台样式代码,性能就会提高。

按照建议,我正在执行所有这些步骤:


  • 由于设计方式的原因,我有2种不同的单元格变化,并且不能具有一致的行高。无论单元格如何变化,行背景始终为3张图像中的1张,并基于行索引。 0:top_row_image,n-1:bottom_row_image,所有其他:middle_row_image
  • 我正在ViewController的viewDidLoad中加载用于背景的图像。
  • 我没有任何drawRect代码,因为我让单元格内的UITextField处理了
  • Cell的图层设置为不透明
  • 单元标识符正在重用
  • 不从NIB文件
  • 加载单元


    基本上,我想用不同的顶行,中间行和底行背景图像来设置表格部分各行的样式,具体取决于行类型。谁能建议一种更好的方法在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时停止切换每个单元格的背景图像,将会获得显着的性能提升。

    听起来您具有三种单元格(“顶部”,“中间”和“底部”)。您可以停止重复使用它们,因此每次使用时都必须重置其背景图像。

    相反,您可以根据其在表中的位置使用不同的标识符来初始化表单元格的实例。这样,您将创建具有“顶部”标识符的单个单元格,具有“底部”标识符的单个单元格以及具有“中间”标识符的许多单元格。然后,仅在初始化单元格时才可以设置其背景图像。只要您尝试重复使用具有适当标识符的单元格,就不再需要每次更改其背景图像。

    关于ios - 通过自定义UITableViewCells提高ViewController的加载速度(记录已损坏),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12361190/

    相关文章:

    ios - 在函数内部使用关键字 guard 是否会自动使函数的参数在 swift 中成为可选参数?

    ios - 如何在数据库中存储数据(sqlite)

    ios - CFBundleDisplayName 返回 'null'

    itunes - iTunes 同步/文件传输完成时 iOS 中的通知回调

    ios - 调用 reloadData() 时 UITableView 的预期 `contentOffset` 是什么?

    iphone - 从数据库中插入数据到表中

    php - 如何在 Swift 中访问从 PHP 传递的数组中的数据?

    ios - 如何检查设备是 iPad 还是 iPhone 不工作

    ios - 根据音乐点亮

    uitableview - 解析后端和 Swift UITableview