UITableView中的单元格imageView直到被选中才会出现

时间:2021-01-18 21:12:46
  1. Here is a video of the problem: http://youtu.be/Jid0PO2HgcU

    下面是这个问题的视频:http://youtu.be/Jid0PO2HgcU

  2. I have a problem when trying to set the image for the [cell imageView] in a UITableView from the asset library.

    在试图从资产库的UITableView中为[cell imageView]设置图像时,我遇到了一个问题。

The image is loaded but it doesn't appear in the cell until I touch (select) that cell. Here is my code that sets the imageView of the cell:

图像被加载,但是直到我触摸(选择)该单元时它才出现在单元格中。下面是设置单元格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]; 
}

The above code is part of the:

上述守则包括:

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

Any ideas?

什么好主意吗?

8 个解决方案

#1


39  

I think in this case you're using a iOS defined UITableViewCell (and not a custom one), that is one of those cells that you get from "initWithStyle:reuseIdentifier:". Now these cells are internally built in such way that if you don't assign some content immediately the corresponding subview will not be added in the cell's contentView hierarchy. This kind of behavior is typical of complex custom views, where the final cell layout can be determined only when all its subviews have their content fully specified. (E.g. you have two labels, let's say label A and label B, label A is multirow and you want to add label-B immediately below label-A, then you can place label-B correctly only once you have the label-A content and you calculate its height.). So I suppose the built-in iOS table cells are done in the same way and the subviews hierarchy is built at the "layoutSubviews" stage.

我认为在本例中,您使用的是iOS定义的UITableViewCell(而不是自定义的UITableViewCell),这是您从“initWithStyle:reuseIdentifier:”中获得的单元之一。现在,这些单元格的内部构建方式是,如果您不立即分配某些内容,那么相应的子视图将不会被添加到单元格的contentView层次结构中。这种行为是复杂自定义视图的典型,只有在其所有子视图的内容都已完全指定时,才能确定最终的单元格布局。(例如,你有两个标签,比如标签A和标签B,标签A是多行的,你想要在标签A下面加上标签B,那么你只有在你有标签A内容并计算它的高度之后才能正确地放置标签B)。因此,我认为内置的iOS表单元格也是这样做的,子视图层次结构构建在“layoutSubviews”阶段。

In your case you create the cell but defer the time the image is provided. But at this point the layoutSubviews has been called yet and without any image the corresponding imageView is not even allocated and added in the contentView hierarchy!

在您的例子中,您创建了单元格,但是延迟了提供映像的时间。但是在这一点上,layoutSubviews已经被调用,并且没有任何图像,相应的imageView甚至没有被分配和添加到contentView层次结构中!

So, according to me, the solution for you is just to assign immediately a "placeholder" for your asset (the placeholder can be a transparent image of course) which will guarantee you of the internal UIImageView creation. Be careful with the image size, it should be close to the expected image size, for the same reason explained above. As soon as your finish block is called the image view should be already there and the image will appear.

所以,根据我的说法,你的解决方案是立即为你的资产分配一个“占位符”(占位符当然可以是一个透明的图像),它将保证你的内部UIImageView创建。注意图像大小,它应该接近预期的图像大小,原因与上面解释的一样。一旦你的完成块被调用,图像视图应该已经在那里并且图像将会出现。

The reason why when you tap on the cell the image appears, is due to the fact that this operation calls the layoutSubviews again. In this case the whole code is probably re-executed and as you already called "setImage:" before then the internal "image" property is set and the contentView hierarchy will be rebuilt with the new image.

当您点击单元格时,图像出现的原因是这个操作再次调用layoutSubviews。在这种情况下,整个代码可能会被重新执行,就像您已经调用的“setImage:”在那之前,内部的“image”属性将被设置,而contentView层次结构将以新的映像重新构建。

Another possible solution to your problem is of course to use a "custom" UITableViewCell (e.g. loaded from a Nib). In such case all your subviews will be loaded and you will simply access to the UIImageView using his tag (read apple docs to know more about this useful technique to create table view cells from a Nib file).

另一种可能的解决方法是使用“自定义”UITableViewCell(例如从Nib加载)。在这种情况下,所有的子视图都将被加载,您只需使用他的标记访问UIImageView(请阅读苹果文档,以了解更多关于从Nib文件创建表视图单元的有用技术)。

#2


26  

you need to layout cell after image set

您需要在图像集之后设置单元格。

just like

就像

[cell setNeedsLayout];

(细胞setNeedsLayout);

#3


6  

I scratched my head for so long and finally figured it out.

我挠了很久的头,终于想通了。

My mistake was that I was setting image in cell.imageView when I should be setting my actual outlet cell.eventImageView. It was messing with the generic imageview provided in UITableViewCell. Hope it helps somebody.

我的错误是我在单元格中设置了图像。当我要设置我的实际outlet cell.eventImageView时,imageView。它破坏了UITableViewCell提供的通用imageview。希望它能帮助别人。

#4


1  

This is my way how i solved these problem, i know is not the best but that work :)

这是我解决这些问题的方式,我知道这不是最好的,但那是我的工作。

    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;
    });

#5


1  

In my case I was setting up a prototype cell through a Storyboard, but was accidentally using the dequeueCellWithIdentifier:forIndexPath method instead of dequeueCellWithIdentifier:.

在我的例子中,我正在通过故事板设置一个原型单元格,但是不小心使用了dequeueCellWithIdentifier:forIndexPath方法而不是dequeueCellWithIdentifier:。

The first method is only to be used when appropriating cells to a tableview through the programmatic UITableView registerClass:forReuseIdentifier: or registerNib:forReuseIdentifier methods.

第一个方法仅用于将单元格通过编程UITableView registerClass: useidentifier:或registerNib: useidentifier方法来使用。

#6


0  

I was having a similar problem. I had registered the default UITableViewCell class instead of my custom class.

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

I had this:

我有这个:

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

but I should have had this:

但我应该有这个:

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

The cell creation all looked to be working as I stepped through the debugger, but nothing showed up until I selected each row.

当我通过调试器时,单元格的创建看起来都在工作,但是在我选择每一行之前没有显示任何内容。

#7


0  

Sometime it happens when you are using custom UITableViewCell with labels, images etc but also somewhere you are setting default UILabel of cell. for example

有时,当你使用自定义UITableViewCell和标签、图像等时,你也在设置单元格的默认UILabel。例如

customCell.textLabel.text = @"some text"

To solve this problem, avoid using default label, instead add your own UILabel in your custom cell.

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

#8


0  

I get same issue when i use this code:

当我使用这个代码时,我也遇到了同样的问题:

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!";
        }

But I fix it by replace:

但是我把它替换为:

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

To:

:

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

#1


39  

I think in this case you're using a iOS defined UITableViewCell (and not a custom one), that is one of those cells that you get from "initWithStyle:reuseIdentifier:". Now these cells are internally built in such way that if you don't assign some content immediately the corresponding subview will not be added in the cell's contentView hierarchy. This kind of behavior is typical of complex custom views, where the final cell layout can be determined only when all its subviews have their content fully specified. (E.g. you have two labels, let's say label A and label B, label A is multirow and you want to add label-B immediately below label-A, then you can place label-B correctly only once you have the label-A content and you calculate its height.). So I suppose the built-in iOS table cells are done in the same way and the subviews hierarchy is built at the "layoutSubviews" stage.

我认为在本例中,您使用的是iOS定义的UITableViewCell(而不是自定义的UITableViewCell),这是您从“initWithStyle:reuseIdentifier:”中获得的单元之一。现在,这些单元格的内部构建方式是,如果您不立即分配某些内容,那么相应的子视图将不会被添加到单元格的contentView层次结构中。这种行为是复杂自定义视图的典型,只有在其所有子视图的内容都已完全指定时,才能确定最终的单元格布局。(例如,你有两个标签,比如标签A和标签B,标签A是多行的,你想要在标签A下面加上标签B,那么你只有在你有标签A内容并计算它的高度之后才能正确地放置标签B)。因此,我认为内置的iOS表单元格也是这样做的,子视图层次结构构建在“layoutSubviews”阶段。

In your case you create the cell but defer the time the image is provided. But at this point the layoutSubviews has been called yet and without any image the corresponding imageView is not even allocated and added in the contentView hierarchy!

在您的例子中,您创建了单元格,但是延迟了提供映像的时间。但是在这一点上,layoutSubviews已经被调用,并且没有任何图像,相应的imageView甚至没有被分配和添加到contentView层次结构中!

So, according to me, the solution for you is just to assign immediately a "placeholder" for your asset (the placeholder can be a transparent image of course) which will guarantee you of the internal UIImageView creation. Be careful with the image size, it should be close to the expected image size, for the same reason explained above. As soon as your finish block is called the image view should be already there and the image will appear.

所以,根据我的说法,你的解决方案是立即为你的资产分配一个“占位符”(占位符当然可以是一个透明的图像),它将保证你的内部UIImageView创建。注意图像大小,它应该接近预期的图像大小,原因与上面解释的一样。一旦你的完成块被调用,图像视图应该已经在那里并且图像将会出现。

The reason why when you tap on the cell the image appears, is due to the fact that this operation calls the layoutSubviews again. In this case the whole code is probably re-executed and as you already called "setImage:" before then the internal "image" property is set and the contentView hierarchy will be rebuilt with the new image.

当您点击单元格时,图像出现的原因是这个操作再次调用layoutSubviews。在这种情况下,整个代码可能会被重新执行,就像您已经调用的“setImage:”在那之前,内部的“image”属性将被设置,而contentView层次结构将以新的映像重新构建。

Another possible solution to your problem is of course to use a "custom" UITableViewCell (e.g. loaded from a Nib). In such case all your subviews will be loaded and you will simply access to the UIImageView using his tag (read apple docs to know more about this useful technique to create table view cells from a Nib file).

另一种可能的解决方法是使用“自定义”UITableViewCell(例如从Nib加载)。在这种情况下,所有的子视图都将被加载,您只需使用他的标记访问UIImageView(请阅读苹果文档,以了解更多关于从Nib文件创建表视图单元的有用技术)。

#2


26  

you need to layout cell after image set

您需要在图像集之后设置单元格。

just like

就像

[cell setNeedsLayout];

(细胞setNeedsLayout);

#3


6  

I scratched my head for so long and finally figured it out.

我挠了很久的头,终于想通了。

My mistake was that I was setting image in cell.imageView when I should be setting my actual outlet cell.eventImageView. It was messing with the generic imageview provided in UITableViewCell. Hope it helps somebody.

我的错误是我在单元格中设置了图像。当我要设置我的实际outlet cell.eventImageView时,imageView。它破坏了UITableViewCell提供的通用imageview。希望它能帮助别人。

#4


1  

This is my way how i solved these problem, i know is not the best but that work :)

这是我解决这些问题的方式,我知道这不是最好的,但那是我的工作。

    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;
    });

#5


1  

In my case I was setting up a prototype cell through a Storyboard, but was accidentally using the dequeueCellWithIdentifier:forIndexPath method instead of dequeueCellWithIdentifier:.

在我的例子中,我正在通过故事板设置一个原型单元格,但是不小心使用了dequeueCellWithIdentifier:forIndexPath方法而不是dequeueCellWithIdentifier:。

The first method is only to be used when appropriating cells to a tableview through the programmatic UITableView registerClass:forReuseIdentifier: or registerNib:forReuseIdentifier methods.

第一个方法仅用于将单元格通过编程UITableView registerClass: useidentifier:或registerNib: useidentifier方法来使用。

#6


0  

I was having a similar problem. I had registered the default UITableViewCell class instead of my custom class.

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

I had this:

我有这个:

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

but I should have had this:

但我应该有这个:

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

The cell creation all looked to be working as I stepped through the debugger, but nothing showed up until I selected each row.

当我通过调试器时,单元格的创建看起来都在工作,但是在我选择每一行之前没有显示任何内容。

#7


0  

Sometime it happens when you are using custom UITableViewCell with labels, images etc but also somewhere you are setting default UILabel of cell. for example

有时,当你使用自定义UITableViewCell和标签、图像等时,你也在设置单元格的默认UILabel。例如

customCell.textLabel.text = @"some text"

To solve this problem, avoid using default label, instead add your own UILabel in your custom cell.

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

#8


0  

I get same issue when i use this code:

当我使用这个代码时,我也遇到了同样的问题:

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!";
        }

But I fix it by replace:

但是我把它替换为:

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

To:

:

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