views:

2115

answers:

6

Is there an easy way to trigger a [UITableView reloadData] from within a UITableViewCell? I am loading remote images to be displayed after the initial table display, and updating the image with self.image = newImage does not refresh the table. Resetting the cell's text value does refresh the table, but this seems sloppy.

MyTableViewCell.h

@interface MyTableViewCell : UITableViewCell {}
- (void)imageWasLoaded:(ImageData *) newImage;

MyTableViewCell.m

@implementation MyTableViewCell
- (void)imageWasLoaded:(UIImage *) newImageData {
    self.image = newImage; //does not refresh table

    //would like to call [self.tableView reloadData] here,
    //but self.tableView does not exist.

    //instead I use the below line
    self.text = self.text; //does refresh table
}
@end
A: 

try [yourtableview reloadData]; after setting the image to a new image

Rahul Vyas
That's going to be very expensive if you have a lot of data. It's better to just update the cell that loaded the image.
Sam Soffes
A: 

I am not exactly sure how you have a reference to the table cell but if you are inside a method in the UITableViewController class - just call:

[self.tableView reloadData];
Grouchal
A: 

It is less expensive to only reload the sections/rows that need reloading. In iPhone SDK 3.0 there are some methods for doing just that.

bare_nature
setNeedsLayout is 2.0+: http://tuvix.apple.com/iphone/library/documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instm/CALayer/setNeedsLayout
bbrown
A: 

Hmm. So imageWasLoaded: is a delegate method called by some asynchronous image loading code? Actually it seems weird that setting self.image does not update the image. Have you tried to add your own UIImageView to the cell rather than using the image property? Might be kind of a hack, but this way the image should update right away (without you having to reload the whole table view, which is definitely not desireable).

Even better: If you are using SDK 3.0, you can use the new imageView property in UITableViewCell (I have not tried this, though):

self.imageView.image = newImage;

Actually, I needed to do exactly the same some weeks ago. However, my approach was to subclass UIImageView and do all the asynchronous image loading/updating in that class. The main reason I did it this way was that I wanted to have a generic and reusable component which can be used in different table view cells (or elsewhere).

Daniel Rinser
+1  A: 

I did the exact thing that you're trying to do. The thing you're looking for is needsLayout. To wit (this is a notification observer on my UITableViewCell subclass):

- (void)reloadImage:(NSNotification *)notification
{
    UIImage *image = [[SSImageManager sharedImageManager] getImage:[[notification userInfo] objectForKey:@"imageUrl"];
    [self setImage:image];
    [self setNeedsLayout];
}

This will pop in your image without having to reload the entire table, which can get very expensive.

bbrown
This is exactly what I was looking for. Thanks!
Arrel
A: 

Get a reference to the containing UITableView using the superview property. Then tell it to "reloadData":

UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];
CodeGrue