【发布时间】:2012-09-11 00:26:06
【问题描述】:
我有一个带有 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 处理
- 单元格的图层设置为不透明
- 小区标识符正在被重复使用
- 不从 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;
}
【问题讨论】:
-
我很困惑,但每个单元格都有不同的背景?你大约有多少个细胞?如果您有许多具有不同背景的单元格,那么它们应该被动态加载。通过在 viewdidload 中加载所有内容,您正在使界面等待一切准备就绪。此外,如果您正在调试并且您有很多单元格,请确保您没有 NSLOG 内容会增加加载时间。
-
我有 3 种不同的背景类型。每个部分的顶行单元格应该有一种类型(它有一个向下的曲线),中间行有另一个(标准图像),最后,每个部分的底行有一个第三种类型(这个图像有一个向上的曲线)。
-
我一共15行,分成4个部分。
标签: ios ios5 uitableview