问题描述
我有一个带有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问题中提到的建议:
I think I'm following as much as the recommendation noted in this other SO question:Tricks for improving iPhone UITableView scrolling performance
I我也遵循了这篇文章,以确保我没有做一些愚蠢的事情:
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:
基本上,我想根据表格的行类型,为每个表格的部分行设置不同的顶部,中间和底部行背景图像。任何人都可以建议在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加载速度(破纪录)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!