我有一个表格视图,其中包含填充单元格的大图像,并且行高是根据图像大小设置的。不幸的是,当滚动到下一个单元格时,表格会严重抖动。
有人告诉我,如果我在将行高和图像加载到表中之前对其进行缓存,那么我的表视图将滚动得更顺畅。
我的所有数据都存储在 plist 中。
我该如何去抓东西?
代码是什么样的?它在哪里?
Thanks!
这是我加载图像的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *detailTableViewCellIdentifier = @"Cell";
DetailTableViewCell *cell = (DetailTableViewCell *)
[tableView dequeueReusableCellWithIdentifier:detailTableViewCellIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"DetailTableViewCell" owner:self options:nil];
for(id currentObject in nib)
{
cell = (DetailTableViewCell *)currentObject;
}
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *MainImagePath = [Path stringByAppendingPathComponent:([[appDelegate.sectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:@"MainImage"])];
cell.mainImage.image = [UIImage imageWithContentsOfFile:MainImagePath];
return cell;
}
我还使用以下方法来计算行高:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
AppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *MainImagePath = [Path stringByAppendingPathComponent:([[appDelegate.sectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:@"MainImage"])];
UIImage *imageForHeight = [UIImage imageWithContentsOfFile:MainImagePath];
imageHeight = CGImageGetHeight(imageForHeight.CGImage);
return imageHeight;
}
编辑:这是下面的最终代码。
#define PHOTO_TAG 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Photo";
UIImageView *photo;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIImage *theImage = [UIImage imageNamed:[[appDelegate.sectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:@"MainImage"]];
imageHeight = CGImageGetHeight(theImage.CGImage);
imageWidth = CGImageGetWidth(theImage.CGImage);
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
photo = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imageWidth, imageHeight)] autorelease];
photo.tag = PHOTO_TAG;
[cell addSubview:photo];
} else {
photo = (UIImageView *) [cell viewWithTag:PHOTO_TAG];
[photo setFrame:CGRectMake(0, 0, imageWidth, imageHeight)];
}
photo.image = theImage;
return cell;
}
缓存并不是提高表视图性能的灵丹妙药。仅当需要计算一些昂贵的内容并且您可以避免计算它时,缓存才有价值。另一方面,如果您的 UITableViewCell 中有太多视图,那么缓存对您不起作用。如果行高都相同,则无需缓存任何内容。如果你使用+[UIImage imageNamed:]
,那么系统已经为您缓存了您的图像。
UITableViewCells 最常见的一阶问题是在其中放置了太多子视图。你是如何构建你的细胞的?您是否花时间学习《表视图编程指南》,特别是仔细观察表格视图单元格?理解这份文档将会为你省去很多以后的痛苦。
编辑:(基于上面的代码)
首先,您获取一个可重用单元,然后立即将其丢弃,读取 NIB 并迭代所有顶级对象以查找单元(看起来几乎与您刚刚丢弃的单元一模一样)。然后计算出一个字符串,用它来打开文件并读取内容。每当 UITableView 需要一个新单元格时,您都会执行此操作,这是很多。并且您对相同的行一遍又一遍地执行此操作。
然后,当 UITableView 想要知道高度时,您再次从磁盘读取图像。每次 UITableView 请求时你都会这样做(它可能会多次请求同一行,尽管它确实尝试优化这一点)。
您应该首先阅读上面链接的 UITableView 编程指南。这希望能有很大帮助。完成此操作后,您应该考虑以下事项:
您指出该单元格中只有一个图像视图。您真的需要 NIB 吗?如果您确实坚持使用 NIB(并且在某些情况下有理由使用它们),请阅读有关如何实现基于 NIB 的单元的编程指南。你应该使用IBOutlet
,不尝试迭代顶级对象。
+[UIImage imageNamed:]
将自动在您的资源目录中查找文件,而无需您计算出捆绑包的路径。它还将cache自动为您提供这些图像。
要点是-dequeueReusableCellWithIdentifier:
是获取 UITableView 不再使用的单元格,并且您可以重新配置该单元格,而不是创建一个新单元格。你正在呼唤它,但你立刻就把它扔掉了。您应该检查它是否返回 nil,如果返回,则仅将其从 NIB 中加载。否则,您只需更改图像即可。再次阅读编程指南;这方面的例子有很多很多。只要确保你真正尝试理解什么-dequeueReusableCellWithIdentifier:
正在做的事情,不要将其视为您此时在程序中键入的内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)