UITableView中的cell imageView直到被选中才出现

30
  1. 这里有一个问题的视频: http://youtu.be/Jid0PO2HgcU

  2. 我在尝试从资产库中设置UITableView中单元格 [cell imageView] 的图像时遇到了问题。

图片被加载了,但是直到我触摸(选择)该单元格之前,它才出现在单元格中。以下是设置单元格的imageView的代码:

//Start loading the image using the image path
NSString *path = [occasion imagePath];

if (path != nil && [path hasPrefix:@"ass"])
{
NSLog(@"photo loaded from assets library");
//testing ALAssestLibrary
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];

ALAssetsLibraryAssetForURLResultBlock resultsBlock = ^(ALAsset *asset)
{
    ALAssetRepresentation *representation = [asset defaultRepresentation];
    CGImageRef imageRef = [representation fullResolutionImage]; 
    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];


    [[cell imageView] setImage:[image imageByScalingAndCroppingForSize:CGSizeMake(36.0, 42.0)]];     

    [image release];
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error){

    NSLog(@"FAILED! due to error in domain %@ with error code %d", error.domain, error.code);
    // This sample will abort since a shipping product MUST do something besides logging a
    // message. A real app needs to inform the user appropriately.
    abort();
};        

//Convert path to an NSUrl
NSURL *url = [NSURL URLWithString:path];


// Get the asset for the asset URL to create a screen image.
[assetsLibrary assetForURL:url resultBlock:resultsBlock failureBlock:failureBlock];
// Release the assets library now that we are done with it.
[assetsLibrary release]; 
}

上面的代码是以下内容的一部分:

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

有任何想法吗?


我相信这篇文章与你的问题相关。你可以看看它。 - Fernando Madruga
8个回答

43
我认为在这种情况下,您正在使用一个由iOS定义的UITableViewCell(而不是自定义的),这是您从“initWithStyle:reuseIdentifier:”中获得的其中之一。现在,这些单元格在内部构建时的方式是,如果您不立即分配一些内容,则相应的子视图将不会添加到单元格的contentView层次结构中。这种行为是复杂自定义视图的典型行为,其中最终单元格布局只能在所有子视图的内容完全指定时确定。(例如,您有两个标签,假设标签A和标签B,标签A是多行的,您希望立即在标签A下方添加标签B,那么只有当您拥有标签A的内容并计算其高度后,您才能正确地放置标签B)。因此,我想内置的iOS表格单元格也是以同样的方式完成的,并且子视图层次结构是在“layoutSubviews”阶段构建的。
在您的情况下,您创建了单元格,但推迟了提供图像的时间。但此时尚未调用layoutSubviews,并且没有任何图像,对应的imageView甚至没有被分配并添加到contentView层次结构中!
因此,对我来说,您的解决方案就是立即为您的资产分配“占位符”(占位符可以是透明图像),这将向您保证内部UIImageView的创建。请注意图像大小,它应该接近预期的图像大小,原因与上述相同。一旦完成块被调用,图像视图应该已经存在,并且图像将出现。
当您点击单元格时图像出现的原因是,这个操作再次调用layoutSubviews。在这种情况下,整个代码可能会重新执行,并且由于您之前已经调用了“setImage:”,因此内部的“image”属性被设置,contentView层次结构将用新图像重建。
解决您问题的另一个可能的解决方案当然是使用“自定义”UITableViewCell(例如,从Nib加载)。在这种情况下,您的所有子视图都将被加载,您将仅使用标签访问UIImageView(阅读苹果文档以了解有关从Nib文件创建表视图单元格的有用技术的更多信息)。

1
我已经完成了占位符的解决方案,它就像魔法一样奏效。我卡了一段时间。在if语句之后,这是代码:UIImage *placeholderImage = [UIImage imageNamed:@"placeholder.png"]; [[cell imageView] setImage:[placeholderImage imageByScalingAndCroppingForSize:CGSizeMake(36.0, 42.0)]]; - Ali
2
Viggio对问题的评估是正确的,然而更简单的解决方案是在将图像分配给单元格的图像视图后立即调用layoutSubviews方法。这将导致单元格再次经过布局过程。由于此时图像存在,因此它将出现! - mklbtz
谢谢,你救了我。 - Héctor

28
您需要在图片设置后布置单元格。
就像这样:

[cell setNeedsLayout];


6

我思考了很久,最终弄清楚了。

我的错误在于我设置图像时使用的是 cell.imageView,而实际上应该使用我的实际输出 cell.eventImageView。这会影响到UITableViewCell提供的通用图像视图。希望能对某些人有所帮助。


1
这是我解决这些问题的方法,虽然不是最好的,但它有效 :)
    UIImage *thumbnailImage = ...

    dispatch_async(dispatch_get_main_queue(), ^{
        [cell.imageView setImage:thumbnailImage];

        UITableViewCellSelectionStyle selectionStyle = cell.selectionStyle;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        [cell setSelected:YES];
        [cell setSelected:NO];
        cell.selectionStyle = selectionStyle;
    });

1
在我的情况下,我正在通过Storyboard设置原型单元格,但意外使用了dequeueCellWithIdentifier:forIndexPath方法而不是dequeueCellWithIdentifier:
仅当通过编程的UITableView registerClass:forReuseIdentifier:registerNib:forReuseIdentifier方法将单元格适用于表视图时,才应使用第一种方法。

0

我遇到了类似的问题。我注册了默认的UITableViewCell类,而不是我的自定义类。

我原本写的是:

tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: visibilityCellIdentifier)

但我应该有这个:

tableView.registerClass(VisibilityCell.self, forCellReuseIdentifier: visibilityCellIdentifier)

当我通过调试器逐步执行时,所有单元格的创建似乎都正常工作,但在我选择每一行之前没有显示任何内容。


0

当我使用这段代码时,我遇到了相同的问题:

cell = [tableView dequeueReusableCellWithIdentifier:kCellSection1 forIndexPath:indexPath];
        if (indexPath.row == 0) {
            cell = [[UITableViewCell alloc]  initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];
            cell.textLabel.text = @"Vote Up for me if it help for you!";
        }

但我通过替换来修复它:

cell = [[UITableViewCell alloc]  initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];

To:

cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];

-1
有时候,当您使用带有标签、图像等的自定义UITableViewCell时,也会在某些地方设置单元格的默认UILabel。例如:
customCell.textLabel.text = @"some text"

为了解决这个问题,请避免使用默认标签,而是在您的自定义单元格中添加自己的UILabel。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接