2

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

我想我正在遵循其他 SO 问题中提到的建议: 提高 iPhone UITableView 滚动性能的技巧

我还关注了这篇文章以确保我没有做一些愚蠢的事情: 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 处理
  • 单元格的图层设置为不透明
  • 小区标识符正在被重用
  • 不从 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;        
}
4

1 回答 1

0

我认为,如果您停止在每次调用cellForRowAtIndexPath.

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

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

于 2012-09-11T01:08:24.253 回答