简体   繁体   中英

cell imageView in UITableView doesn't appear until selected

  1. Here is a video of the problem: 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.

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:

//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?

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. (Eg 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.

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!

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.

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.

Another possible solution to your problem is of course to use a "custom" UITableViewCell (eg 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).

you need to layout cell after image set

just like

[cell setNeedsLayout];

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.

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

In my case I was setting up a prototype cell through a Storyboard, but was accidentally using the dequeueCellWithIdentifier:forIndexPath method instead of 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.

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

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.

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

customCell.textLabel.text = @"some text"

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

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];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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