I am successfully loading thumbnail images from blog posts asynchronously into my UITableView.
The issue I'm having is that the images only appear if I tap the cell OR if I scroll down.
When I tap the cell, the image appears on the left, pushing the Title and Subtitle to the right.
When I scroll down, the images appear where they should in the cells as they are revealed.
Here's my code (I'm using AFNetworking):
#import "UIImageView+AFNetworking.h"
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return posts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *post = [posts objectAtIndex:indexPath.row];
NSString *postpictureUrl = [post objectForKey:@"picture"];
[cell.imageView setImageWithURL:[NSURL URLWithString:postpictureUrl]];
cell.textLabel.text = [post objectForKey:@"post_text"];
cell.detailTextLabel.text = [post objectForKey:@"post_author_name"];
return cell;
}
I am seeing this in the iPhone 6.0 simulator, XCode 4.5, OSX MtLion.
Any ideas why the images are not drawn on the initial screen?
The issue is resolved by putting a placeholder in this line
The placeholder needs to have dimension ratio similar to the thumbnail to avoid distortion.
I scratched my head for long and finally figured it out.
My mistake was that I was setting image in
cell.imageView
when I should be setting my actual outletcell.eventImageView
. It was messing with the generic imageview provided inUITableViewCell
. Hope it helps somebody.The thing you want to be aware of when mixing asynch and tables is that the asynch finishes at an unknown time in the future, possibly after the cell is scrolled away, removed, reused, etc.
Also, the image that gets pulled from the web is lost if that cell is scrolled away. Not sure if AFNetworking caches for you, but it might be better to not assume. Here's a solution using native networking:
Now, a no-nonsense asynch load without any 3rd party help
For this to work, the posts should be created as NSMutableDictionary...
Alternatively, if it's hard to change the posts model directly, you can setup another structure to cache the downloaded images. A mutable dictionary keyed by the url strings is a good structure to use:
Now, when configuring the cell, see if there's a cached image by checking the cache...
And once an image is downloaded, cache it...
this is my solution, using a category for UIImageView.
NOTE: since we perform self.image = nil in the first line, you must set a placeholder image for the cell.ImageView after calling this method.
and the category:
I'm pretty late to the party, but if you dig a bit deeper in the UIImageView+AFNetworking docs you'll find the method
– setImageWithURLRequest:placeholderImage:success:failure:
which you can use to reload the cell when the image is available: