简体   繁体   English

当单元格具有UIImageView子视图时,UITableView会经历不连贯的滚动

[英]UITableView experiences choppy scrolling when cell has a UIImageView subview

This has been driving me crazy for the better part of the day. 这让我在一天中的大部分时间都疯了。

I've got a UITableView with UIImageViews. 我有一个UITmageView的UITableView。 These imageviews load a locally saved PNG-file in the cellForRow-function of the tableview, and this works fine except the tableview will stop scrolling for a fraction of a second when a cell with an image in it scrolls into sight so to speak. 这些图像视图在tableview的cellForRow函数中加载了一个本地保存的PNG文件,这个工作正常,但是当一个带有图像的单元格滚动到视线中时,tableview将停止滚动几分之一秒。 I've trawled StackOverflow and google for an answer but I've come up short - so any help will be greatly appreciated. 我已经搜索了StackOverflow并谷歌寻求答案,但我已经做得很短 - 所以任何帮助都将非常感激。

Here is my code for the CellForRow-function: 这是我的CellForRow函数代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];



    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    if([currSection isEqualToString:@"composer"]){

        MySlide *s = [slidesArray objectAtIndex:indexPath.row];

        cell.textLabel.hidden = YES;
        UIImageView *whiteView = [[UIImageView alloc] initWithFrame:CGRectMake((projectsTable.frame.size.width/2)-150, 4, 204.8, 153.6)];

        if([s.slideImage isEqualToString:@""] || s.slideImage == nil){
            //no custom image in this cell - go with default background image

            whiteView.image = [UIImage imageNamed:@"cellback2.png"];
            whiteView.backgroundColor = [UIColor whiteColor];
        }else{
            cell.layer.shouldRasterize = YES;
            cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

            NSData *data = [[NSData alloc] initWithContentsOfFile:s.slideImage];

            UIImage *im = [[UIImage alloc] initWithData:data];


            whiteView.image = im;

            whiteView.image = [self imageWithImage:whiteView.image CovertToSize:CGSizeMake(204.8,153.6)];
            whiteView.backgroundColor = [UIColor whiteColor];

        }


        [cell.contentView addSubview:whiteView];

        [whiteView release];



        cell.accessoryType = UITableViewCellAccessoryNone;

    }


  return cell;  
}

There are a couple of changes to be made, first off the UIImageView s should be added when the cell is generated, rather than every time tableView:cellForRowAtIndexPath: is hit (as @Vishy suggests). 有一些更改要做,首先应该在生成单元格时添加UIImageView ,而不是每次tableView:cellForRowAtIndexPath:被命中(如@Vishy建议的那样)。 Secondly you should cache the images you are loading from the documents directory ( [UIImage imageNamed:] does this automatically for bundle resources). 其次,您应该从文档目录缓存正在加载的图像( [UIImage imageNamed:]会自动为捆绑资源执行此操作)。

@interface MyViewController () {

    NSMutableDictionary *_imageCache;
}

@end


@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // other viewDidLoad stuff...

    _imageCache = [[NSMutableDictionary alloc] init];
}

- (void)viewDidUnload {
    [super viewDidUnload];

    // other viewDidUnload stuff...

    [_imageCache release];
    _imageCache = nil;
}

- (void)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        UIImageView *whiteView = [[UIImageView alloc] initWithFrame:CGRectMake((projectsTable.frame.size.width/2)-150, 4, 204.8, 153.6)];
        whiteView.tag = 111;
        whiteView.backgroundColor = [UIColor whiteColor];

        [cell.contentView addSubview:whiteView];

        [whiteView release];
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.textLabel.hidden = YES;
    }

    UIImageView* iView = (UIImageView*) [cell.contentView viewWithTag:111];


    if([currSection isEqualToString:@"composer"]) {

        MySlide *s = [slidesArray objectAtIndex:indexPath.row];

        if([s.slideImage isEqualToString:@""] || s.slideImage == nil) {

            //no custom image in this cell - go with default background image
            iView.image = [UIImage imageNamed:@"cellback2.png"];
        }
        else {

            cell.layer.shouldRasterize = YES;
            cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

            // use the image path as the cache key
            UIImage *theImage = [_imageCache objectForKey:s.slideImage];
            if (theImage == nil) {

                // load the image and save into the cache
                theImage = [UIImage imageWithContentsOfFile:s.slideImage];
                theImage = [self imageWithImage:theImage CovertToSize:CGSizeMake(204.8, 153.6)];

                [_imageCache setObject:theImage forKey:s.slideImage];
            }

            iView.image = theImage;
        }   
    }
}

@end

As a general rule, tableView:cellForRowAtIndexPath: is a method you need to get out of fast , so loading images from disk should be avoided wherever possible. 作为一般规则, tableView:cellForRowAtIndexPath:是一种快速退出的方法,因此应尽可能避免从磁盘加载图像。

There is also a delay the first time each UIImage is displayed. 第一次显示每个UIImage时也会有延迟。 See this post for details on prompting the work at cache time rather than display time: 有关在缓存时间而不是显示时间提示工作的详细信息,请参阅此帖子:

Setting image property of UIImageView causes major lag 设置UIImageView的图像属性会导致严重滞后

Change the code as per below... 按照以下更改代码......

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

if (cell == nil) 
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    UIImageView *whiteView = [[UIImageView alloc] initWithFrame:CGRectMake((projectsTable.frame.size.width/2)-150, 4, 204.8, 153.6)];
    whiteView.tag = 111;
    whiteView.backgroundColor = [UIColor whiteColor];

    [cell.contentView addSubview:whiteView];

    [whiteView release];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.textLabel.hidden = YES;

}

UIImageView* iView = (UIImageView*) [cell.contentView viewWithTag:111];


if([currSection isEqualToString:@"composer"])
{
    MySlide *s = [slidesArray objectAtIndex:indexPath.row];

    if([s.slideImage isEqualToString:@""] || s.slideImage == nil)
    {
        //no custom image in this cell - go with default background image

        iView.image = [UIImage imageNamed:@"cellback2.png"];
    }
    else
    {
        cell.layer.shouldRasterize = YES;
        cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

        iView.image = [UIImage imageWithContentsOfFile:s.slideImage];
        iView.image = [self imageWithImage:iView.image CovertToSize:CGSizeMake(204.8,153.6)];

    }   
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM