im making a tableview loaded with some NSArrays, the cell contains two labels and a background image view loaded with a URL image. The problem is that the scrolling of the table
To expand on @vborra's answer - the reason why your tableview is slow is that (in your code) the entire image MUST have finished downloading before it displays.
This is because dataWithContentsOfURL:
is a synchronous method. You need to use asynchronous APIs to download images in the background and when they've finished downloading, display them on the screen.
Here is a code snippet from the github page adapted for your example. Make sure you add the folder SDWebImage and it's contents from https://github.com/rs/SDWebImage to your project.
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
int row = [indexPath row];
cell.TitleLabel.text = _Title[row];
cell.DescriptionLabel.text = _content[row];
[cell.CellImageView setImageWithURL:[NSURL URLWithString:_ImageUrl[row]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.CellImageView.contentMode = UIViewContentModeTop;
cell.CellImageView.contentMode = UIContentSizeCategoryMedium;
cell.backgroundColor = [UIColor clearColor];
return cell;
}
Note, if you're downloading images of all different sizes, you may end up with resizing issues which will also decrease your performance. The SDWebImage page has a link to an article to help you with this problem if you come across it. http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/
You may also experience a performance bump when using transparency and tableviews, but it depends on the rest of your code.
AFNetworking is an excellent tool to use, but might be overkill if you're not using networking anywhere else in your app.
You are blocking the main thread with the following line of code:
cell.CellImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:_ImageUrl[row]]]];
My suggestion would be to use AFNetworking and replace the code with the following:
[cell.cellImageView setImageWithURL:[NSURL URLWithString:@"http://example.com/image.png"]];
Also, your pointers should start with a lower case letter. For instance, CellImageView should be cellImageView.
You are calling [NSData dataWithContentsOfURL:[NSURL URLWithString:_ImageUrl[row]]]
from cellForRowAtIndexPath
, which is not good idea. Because it'll go to the server every time a UITableViewCell
is loaded.
You must use Asynchronous image loading & cache. These libraries might help you : (My personal favourite is SDWebImage
)
1) https://github.com/rs/SDWebImage
2) https://github.com/nicklockwood/AsyncImageView
And more, you can refer to the sample code by Apple about LazyTableImages
- https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
UPDATE:
For SDWebImage
follow this guide. It's very good.
http://iosmadesimple.blogspot.in/2013/04/lazy-image-loading.html
load your image like this
//get a dispatch queue
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:mapUrlStr]];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
cell.CellImageView.image = [UIImage imageWithData:imageData]
});
});
Load the image asynchronously(load it as the images come in). Look into great classes such as SDWebImage
https://github.com/rs/SDWebImage