How to cache images ios - ios

I currently have an array with lots of image URLs called images They are being put into my table like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSLog(#"indexPath.row=%ld", (long)indexPath.row);
NSLog(#"images[indexPath.row]=%#", [images objectAtIndex:indexPath.row]);
NSString *stringy = #"http://www.tragicclothing.co.uk/";
NSString *link = [stringy stringByAppendingString: images[indexPath.row]];
NSString* encodedString = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:encodedString]];
cell.thumbnailImageView.image = [UIImage imageWithData: imageData];
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
cell.backgroundView = nil;
return cell;
}
But this is causing a lot of lag when scrolling. How could I cache the data? to prevent this lag? I have seen SDWebImage but I don't quite know how to use it! It seems very complicated.
Should I be using
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:#"myNamespace"];
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image)
{
// image is not nil if image was found
}];

nothing can be simple then SDWebImage
it prodide the following solution
An UIImageView category adding web image and cache management to the Cocoa Touch framework
An asynchronous image downloader
An asynchronous memory + disk image caching with automatic cache expiration handling
#import <SDWebImage/UIImageView+WebCache.h>
NSString* encodedString = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[cell.thumbnailImageView setImageWithURL:[NSURL URLWithString:encodedString]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSLog(#"indexPath.row=%ld", (long)indexPath.row);
NSLog(#"images[indexPath.row + 7]=%#", [images objectAtIndex:indexPath.row + 7]);
NSString *stringy = #"http://www.tragicclothing.co.uk/";
NSString *link = [stringy stringByAppendingString: images[indexPath.row + 7]];
NSString* encodedString = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[cell.thumbnailImageView setImageWithURL:[NSURL URLWithString:encodedString] placeholderImage:[UIImage imageNamed:#"Comp 2_00000.png"]];
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
cell.backgroundView = nil;
return cell;
}

Related

UITableView scrolling not smooth with custom table cell in ios

I am using custom cell.here i load two image and four label. TableView scrolling not smooth.here is my code.
static NSString *simpleTableIdentifier = #"SimpleTableCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellSixPlus" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.cellButtonOutlet.tag = indexPath.row;
[cell.cellButtonOutlet addTarget:self action:#selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
NSManagedObjectModel *device = [self.devices objectAtIndex:indexPath.row];
long int index1 = [languageCode indexOfObject: [NSString stringWithFormat:#"%#",[device valueForKey:#"sourceLang"]]];
long int index2 = [languageCode indexOfObject: [NSString stringWithFormat:#"%#",[device valueForKey:#"destinationLang"]]];
cell.nameLabel1.text = [languageName objectAtIndex:index1];
cell.nameLabel2.text = [languageName objectAtIndex:index2];
cell.nameLabel3.text = [NSString stringWithFormat:#"%#",[device valueForKey:#"sourceText"]];
cell.nameLabel4.text = [NSString stringWithFormat:#"%#",[device valueForKey:#"transilateText"]];
cell.sourceFlagImageview.image = [UIImage imageNamed:[languageName objectAtIndex:index1]];
cell.translateFlagImageview.image = [UIImage imageNamed:[languageName objectAtIndex:index2]];
return cell;
Problem solved by increasing cell height
comment following line of codes and try again :
long int index1 = [languageCode indexOfObject: [NSString stringWithFormat:#"%#",[device valueForKey:#"sourceLang"]]];
long int index2 = [languageCode indexOfObject: [NSString stringWithFormat:#"%#",[device valueForKey:#"destinationLang"]]];
cell.sourceFlagImageview.image = [UIImage imageNamed:[languageName objectAtIndex:index1]];
cell.translateFlagImageview.image = [UIImage imageNamed:[languageName objectAtIndex:index2]];
If it will work fine then you need to assign images in background queue

TableView Slow Scroll

I'm developing and iOS app and my UITableView is kinda slow. I would like to know all the possible reasons for a slow scroll.
Note that I'm using prototype cells in the storyboard and I don't have any images.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
Classification *classification = [classifications objectAtIndex:indexPath.row];
UILabel *teamLabel = (UILabel *) [cell viewWithTag:101];
[teamLabel setText:[classification team]];
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}
Also, it runs smoothly in the simulator.
I'm using an iPad 2.
Download the data asynchronously in your:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Use 2 separated UITableViewCell objects, one to fill with text data, one for images which need to be in thread such as dispatch_async, example from my project:
if (imageUrl.length > 0)
{
NSString *completeURL = #"";
completeURL = [completeURL stringByAppendingString:kPROFILE_IMAGE_URL];
completeURL = [completeURL stringByAppendingString:#"/2/"];
completeURL = [completeURL stringByAppendingString:imageUrl];
completeURL = [completeURL stringByAppendingString:#".png"];
NSString *fileName = [NSString stringWithFormat:#"%#.png", imageUrl];
NSString* path = GetMediaFolder();
BOOL imageExists = [[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:fileName]];
if (imageExists)
{
// NSLog(#"Image exists");
// Update UI
dispatch_async(dispatch_get_main_queue(), ^
{
UITableViewCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = (UIImageView*)[updateCell viewWithTag:kTAG_IMAGE];
imageView.image=[UIImage imageWithContentsOfFile:[path stringByAppendingPathComponent:fileName]];
imageView.layer.cornerRadius = 23.0;
imageView.layer.borderColor = (__bridge CGColorRef)([UIColor clearColor]);
imageView.layer.borderWidth = 1.0;
imageView.clipsToBounds = YES;
imageView.contentMode = UIViewContentModeScaleAspectFill;
[updateCell setNeedsLayout];
});
}
else
{
// NSLog(#"Image not exists");
// Download The Image
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
NSURL *imageURL=[NSURL URLWithString:completeURL];
NSData *image=[NSData dataWithContentsOfURL:imageURL];
[image writeToFile:[path stringByAppendingPathComponent:fileName] atomically:YES];
// Update UI
dispatch_async(dispatch_get_main_queue(), ^
{
UITableViewCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = (UIImageView*)[updateCell viewWithTag:kTAG_IMAGE];
imageView.image=[UIImage imageWithContentsOfFile:[path stringByAppendingPathComponent:fileName]];
imageView.layer.cornerRadius = 23.0;
imageView.layer.borderColor = (__bridge CGColorRef)([UIColor clearColor]);
imageView.layer.borderWidth = 1.0;
imageView.clipsToBounds = YES;
imageView.contentMode = UIViewContentModeScaleAspectFill;
[updateCell setNeedsLayout];
});
});
}
}
}
return cell;
EDIT 1:
I see you don't use images, you still need to download all the data asynchronously and fill it in the new UITableViewCell when download finished (instead of my images downloads, temporary data and downloaded data).

First 3 cells are the same but turn correct once I start scrolling?

So Whenever I launch my app it looks like this and the first 3 cells are all the same. But once I start scrolling up and down it fixes and cell 2 and 3 show the correct information.
This is currently how my code looks like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MyFeedCell";
SampleTableCell *cell = (SampleTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"SampleTableCell" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]]) {
cell = (SampleTableCell *)currentObject;
break;
}
}
}
// Configure the cell.
NSUInteger row = [indexPath row];
NSUInteger count = [_allEntries count];
RSSEntry *entry = [_allEntries objectAtIndex:(count-row-1)];
NSString *imageString = entry.image;
imageString = [imageString stringByReplacingOccurrencesOfString:#"128x67" withString:#"768x432"];
NSLog(#"IMAGE : %#", imageString);
NSURL *imgURL = [[NSURL alloc] initWithString:imageString];
[cell.profilePicture setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:nil]];
NSString *date = [entry.articleDate substringToIndex:12];
cell.datePosted.text = date;
cell.name.text = entry.articleTitle;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Here's a gif of how it's currently functioning
http://gyazo.com/2011099496257445c008a717beabd8fd
The whole topLevelObjects gambit is no longer necessary, replace your code with this and see if your still getting the problem:
//this above #interface
static NSString *CellIdentifier = #"MyFeedCell";
//Put this in viewDidLoad
[self.table registerClass:[SampleTableCell class] forCellReuseIdentifier:CellIdentifier];
[self.table registerNib:[UINib nibWithNibName:#"SampleTableCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SampleTableCell *cell = (SampleTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell.
NSUInteger row = [indexPath row];
NSUInteger count = [_allEntries count];
RSSEntry *entry = [_allEntries objectAtIndex:(count-row-1)];
NSString *imageString = entry.image;
imageString = [imageString stringByReplacingOccurrencesOfString:#"128x67" withString:#"768x432"];
NSLog(#"IMAGE : %#", imageString);
NSURL *imgURL = [[NSURL alloc] initWithString:imageString];
[cell.profilePicture setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:nil]];
NSString *date = [entry.articleDate substringToIndex:12];
cell.datePosted.text = date;
cell.name.text = entry.articleTitle;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}

How to show images in UITableViewCell From NSMutableArray?

I'm doing this :
(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];
cell.imageView.image = [UIImage imageNamed:[[self.articlesArray
objectAtIndex:indexPath.row]objectForKey:#"images"]];
// [cell.imageView setImageWithURL:[NSURL URLWithString:[[self.articlesArray
objectAtIndex:indexPath.row]objectForKey:#"images"]]];
}
return cell;
}
I'm doing this:
cell.imageView.image = [UIImage imageNamed:[[self.articlesArray
objectAtIndex:indexPath.row]objectForKey:#"images"]];
But nothing is showing in my UITableViewCell.
And I want to show image in left of tableViewCell on left side ,
Please tell me how can I do this.
I've done it by myself.
here is the solution, and it works perfectly.
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:
[[self.articlesArray objectAtIndex:indexPath.row]objectForKey:#"images"]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
cell.imageView.image =image;

How to add activity indicator to the image in UITableView?

I have created the Custom tableView and using custom tableView class in Other class to Show the tableView..
I am Loading the image from Server and displaying it in the tableViewRow.. each image is different in it..
On Screen only 7 out of 10 images will come, and when I scroll down the first 3 images are repeating for some time and when those images get load its showing proper images.. but initially till new images will come its showing old images, I want to put a activity indicator to show that the images are loading instead of old images..
I want to add activity Indicator in the place of image, till the image get load..
My code is...
self.tableViewX = tableView;
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
NSString *imageURL = [NSString stringWithFormat: #"www.xyz.image.png"];
cell.thumbnailImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
});
Please assist me with some sample code..
You can use "AsyncImageView" class files it will load image synchronically and it shows the activity indicator while image loading
You can download "AsyncImageView" class files from following link:-
https://www.dropbox.com/s/peazwjvky9fsjd7/Archive.zip
in .m file import AsyncImageView Class
#import "AsyncImageView.h"
in your tableview cell at indexpath method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString *imageURL = [NSString stringWithFormat: #"www.xyz.image.png"];
AsyncImageView *async = [[AsyncImageView alloc]initWithFrame:CGRectMake(0, 0, width, height)];
[async loadImageFromURL:[NSURL URLWithString:imageURL]];
[cell.thumbnailImageView addSubview:async];
}
try this your problem will solve.

Resources