Custom UITableViewCell imageView not updating after setImage
I've got a custom UITableViewCell class whose model object performs an asynchronous download of an image which is to be displayed in the cell. I know I've got the outlets connected properly in IB for WidgetTVC, I know that image data is being properly returned from my server, and I've alloc/init'd the widget.logo UIImage too. Why is the image always blank then in my tableViewCell? Thanks in advance.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Widget *theWidget = [widgetArray objectAtIndex:indexPath.row];
static NSString *CellIdentifier = @"WidgetCell";
WidgetTVC *cell = (WidgetTVC*)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:@"WidgetTVC" owner:self options:nil];
cell = self.widgetTVC;
self.widgetTVC = nil;
}
[cell configureWithWidget:theWidget];
return cell;
}
In my WidgetTVC class, I have the following method:
- (void)configureWithWidget:(Widget*)aWidget {
self.widget = aWidget;
self.nameLbl.text = aWidget.name;开发者_Go百科
[self.logoIvw setImage:aWidget.logo]; // logoIvw is the image view for the logo
}
Finally- I've got the callback method that sets the logo UIImage property on the Widget model object asynchronously (simplified):
(void)didReceiveImage:(ASIHTTPRequest *)request {
// I pass a ref to the Widget's logo UIImage in the userInfo dict
UIImage *anImage = (UIImage*)[request.userInfo objectForKey:@"image"];
UIImage *newImage = [UIImage imageWithData:[request responseData]];
anImage = newImage;
}
In didReceiveImage:
, you're only modifying the local pointer anImage
. You need to set the image
property of your UIImageView
in order to update what gets displayed. Instead of stashing a reference to your widget's UIImage
, pass a reference to the UIImageView
, and in didReceiveImage:
do something like
UIImageView *imageView = (UIImageView*)[request.userInfo objectForKey:@"imageView"];
UIImage *newImage = [UIImage imageWithData:[request responseData]];
imageView.image = newImage;
Perhaps the best solution would be to have your model object have the image as a property and the display object subscribe to the image property's changes through KVO and update itself whenever the image property changes.
OK- there were a couple things wrong here. Thanks to bosmacs and Ed Marty as both of your comments were used to get to the solution.
First, I added a method to the Widget object to get the logo asynchronously:
- (void)asyncImageLoad {
...
// logo is a UIImage
[AsyncImageFetch fetchImage:&logo fromURL:url];
}
And my own AsyncImageFetch class looks like this:
+ (void)fetchImage:(UIImage**)anImagePtr fromURL:(NSURL*)aUrl {
ASIHTTPRequest *imageRequest = [ASIHTTPRequest requestWithURL:aUrl];
imageRequest.userInfo = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:anImagePtr] forKey:@"imagePtr"];
imageRequest.delegate = self;
[imageRequest setDidFinishSelector:@selector(didReceiveImage:)];
[imageRequest setDidFailSelector:@selector(didNotReceiveImage:)];
[imageRequest startAsynchronous];
}
+ (void)didReceiveImage:(ASIHTTPRequest *)request {
UIImage **anImagePtr = [(NSValue*)[request.userInfo objectForKey:@"imagePtr"] pointerValue];
UIImage *newImage = [[UIImage imageWithData:[request responseData]] retain];
*anImagePtr = newImage;
}
Finally, per Ed, I added this to the configureWithWidget method that helps set up my WidgetTVC:
[aCoupon addObserver:self forKeyPath:@"logo" options:0 context:nil];
And when a change is observed, I update the imageView and call [self setNeedsDisplay]. Works like a charm. Any way I can give you both points?
精彩评论