如何缓存表格视图的某些内容?

2023-11-26

我有一个表格视图,其中包含填充单元格的大图像,并且行高是根据图像大小设置的。不幸的是,当滚动到下一个单元格时,表格会严重抖动。

有人告诉我,如果我在将行高和图像加载到表中之前对其进行缓存,那么我的表视图将滚动得更顺畅。 我的所有数据都存储在 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(使用前将#替换为@)

如何缓存表格视图的某些内容? 的相关文章

随机推荐