UITableView caching - uitableview

I create a UITableView, the data comes through a JSON file quite heavy, I wondered if it was possible to put the tableView cached for what is not rafrachisse each segue (push for example)?
I would put my tableView cache for which loads faster loading this page.
My entries JSON (YouTube API v3):
- (void)fetchEntries
{
NSString *searchURL = [API_V3_CHANNEL_URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *searchData = [NSData dataWithContentsOfURL:[NSURL URLWithString:searchURL]];
NSDictionary *searchDict =[NSJSONSerialization JSONObjectWithData:searchData options:NSJSONReadingMutableContainers error:nil];
self.readArray = [searchDict objectForKey:#"items"];
}
and my tableview code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
YouTubeCell *cell = (YouTubeCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Add utility buttons, si besoin effacer de ici
NSMutableArray *leftUtilityButtons = [NSMutableArray new];
[leftUtilityButtons sw_addUtilityButtonWithColor:
UIColorFromRGB(0x2c3e50)
icon:[UIImage imageNamed:#"Icon-message-swipe"]];
[leftUtilityButtons sw_addUtilityButtonWithColor:
UIColorFromRGB(0x475198)
icon:[UIImage imageNamed:#"IconFacebook2"]];
[leftUtilityButtons sw_addUtilityButtonWithColor:
UIColorFromRGB(0x4EA5EC)
icon:[UIImage imageNamed:#"IconTwitter2"]];
[leftUtilityButtons sw_addUtilityButtonWithColor:
UIColorFromRGB(0xe74c3c)
icon:[UIImage imageNamed:#"IconYoutube3"]];
cell.leftUtilityButtons = leftUtilityButtons;
cell.delegate = self;
// à ici
NSDictionary *searchResult = [self.readArray objectAtIndex:indexPath.row];
//Create the button and add it to the cell
//UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//[button addTarget:self
// action:#selector(customActionPressed:)
//forControlEvents:UIControlEventTouchDown];
//[button setTitle:#"Custom Action" forState:UIControlStateNormal];
//button.frame = CGRectMake(150.0f, 5.0f, 150.0f, 30.0f);
//[cell addSubview:button];
cell.ytTitle.text = [[searchResult objectForKey:#"snippet"] valueForKey:#"title"];
cell.ytLink.text = [[[searchResult objectForKey:#"snippet"] objectForKey:#"resourceId"] valueForKey:#"videoId"];
cell.ytLink.hidden = true;
cell.ytTitle.font = [UIFont fontWithName:#"BigNoodleTitling" size:17];
NSString *imageHD = [[[[searchResult objectForKey:#"snippet"] objectForKey:#"thumbnails"] objectForKey:#"high"] valueForKey:#"url"];
NSURL *imageURL = [NSURL URLWithString:imageHD];
NSString *key = imageHD;
NSData *data = [ISCache objectForKey:key];
if (data) {
UIImage *image = [UIImage imageWithData:data];
cell.ytThumbnail.image = image;
} else {
cell.ytThumbnail.image = [UIImage imageNamed:#"hqdefault.jpg"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
[ISCache setObject:data forKey:key];
UIImage *image = [UIImage imageWithData:data];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.ytThumbnail.image = image;
});
});
}
return cell;
}

Related

appending array with url iOS objective c

I have a base url and I have the image names in a array extracted from there server .I am using a collection view, I have to display all the 23 images in the collection view I have two problems
when I try to access cell.imageview.image it says no property image view in cell but in custom cell.h file I have created the outlet and I am using storyboard
2.as one is string base url and other end path or filename of the images in array extracted from john from server
this is how I get from data--
{
"added_by" = 1;
"category_id" = 182;
"category_image" = "shots.png";
"category_name" = Shots;
sequance = 19;
status = 0;
"store_id" = 1;
},
{
"added_by" = 1;
"category_id" = 168;
"category_image" = "classiccocktail.png";
"category_name" = "Classic Cocktails";
sequance = 20;
status = 0;
"store_id" = 1;
},
{
"added_by" = 1;
"category_id" = 167;
"category_image" = "sprit.png";
"category_name" = "Non Alcoholic Bevereges";
sequance = 21;
status = 0;
"store_id" = 1;
},
{
"added_by" = 1;
"category_id" = 162;
"category_image" = "nonalcoholic.png";
"category_name" = "Non Alcoholic Coolers";
sequance = 22;
status = 0;
"store_id" = 1;
}
this is nslog of server reply
This is the slog of the array in which I have stored the data
2017-06-13 10:16:39.181 MenuBar[1703:94836] (
"kinfisherultra.png",
"impotedbeernew.png",
"blendedwhiskyne.png",
"johywalkerbluee.png",
"singlemaltnew.png",
"americanwishkynew.png",
"irishwishkynew.png",
"Belvedere-Vodka.png",
"Ginnew.png",
"Tequilanew.png",
"rumnew.png",
"amarula.png",
"aprities.png",
"breezernew1.png",
"conganbrndynew.png",
"wine&sparkling.png",
"bottels.png",
"cocktailpitchers.png",
"mocktails.png",
"shots.png",
"classiccocktail.png",
"sprit.png",
"nonalcoholic.png"
)
and I have a base url how to get all these images in collection view?
this is customcell.h file
#import <UIKit/UIKit.h>
#interface CustomCell : UICollectionViewCell
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) IBOutlet UILabel *lbl;
#end
customcell.h file
#import "CustomCell.h"
#implementation CustomCell
-(void)awakeFromNib {
UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onButtonTapped:)];
[tap setNumberOfTapsRequired:1];
[self addGestureRecognizer:tap];
[super awakeFromNib];
}
-(void)onButtonTapped:(id)sender
{
//the response to the gesture.
//mind that this is done in the cell. If you don't want things to happen from this cell.
//then you can still activate this the way you did in your question.
}
#end
view controller.hfile
if(!sharedSessionMainQueue){
sharedSessionMainQueue = [NSURLSession sessionWithConfiguration:nil delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
}
[[sharedSessionMainQueue dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; // this is json string
// NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; // you need to convert to dictionary object
NSDictionary *temp=jsonDict;
NSLog(#"Req cust:%#",requestReply);
NSLog(#"requestReply cust liqour category: %#", jsonDict);
NSArray *imgNameArray = [temp valueForKey: #"category_name"];
NSLog(#"$$$%#$$$",imgNameArray);
self.iname=[jsonDict valueForKey:#"category_image"];
NSLog(#"%#",self.iname);
//[self imagedl];
NSDictionary *tempz=[jsonDict valueForKey:#"category_name"];
Photos = [NSArray arrayWithObjects:#"http://test.kre8tives.com/barebones/upload/%#",self.iname, nil];
NSLog(#"^^^%#",tempz);
//NSLog(#"$$%#",[Photos objectAtIndex:]); //Here can show Img's values correctl
// }
// self.recipeImageView.image = [UIImage imageNamed:self.recipeImageName];
}] resume];
_barbutton.target = self.revealViewController;
_barbutton.action = #selector(revealToggle:);
//[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background"]];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)geti{
NSString *temps= [NSString stringWithFormat:#"http://test.kre8tives.com/barebon/upload/%#",self.iname];
UIImage *temp;
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:temps]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(#"%#",response);
//temp.image= [UIImage imageWithData:data];
}];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 23;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//[CustomCell registerClass:[CustomCell class] forCellWithReuseIdentifier:reuseIdentifier];
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
[[[cell contentView] subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIView * contents=[[UIView alloc] initWithFrame:cell.contentView.bounds];
[contents setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:contents];
_imageView.image;
// set tag to the indexPath.row so we can access it later
[cell setTag:indexPath.row];
// add interactivity
UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onButtonTapped:)];
[tap setNumberOfTapsRequired:1];
[cell addGestureRecognizer:tap];
NSString *fileName = [NSString stringWithFormat:#"%#",self.iname]; //objectAtIndex:indexPath];
NSLog(#"%#",fileName);
NSString *baseurl=[NSString stringWithFormat:#"http://test.kre8tives.com/barebon/upload/"];
NSDictionary *doors = [NSMutableArray new];
NSString *base=[NSString stringWithFormat:#"http://test.kre8tives.com/barebon/upload/"];
NSLog(#"%#",doors);
NSString *path = [NSString stringWithFormat:#"%#/%#", baseurl, _iname];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *imgage = [[UIImage alloc] initWithData:data];
//NSString *filePath = [baseurl stringByAppendingPathComponent:fileName];
NSDictionary *dict = self.iname[indexPath.row];
NSLog(#"%#", [self.iname objectAtIndex: indexPath.row]);
NSString *filePath=[NSString stringWithFormat:#"%#%#",baseurl,fileName];
NSString *paths = [NSString stringWithFormat:#"%#/%#", baseurl, [[dict valueForKey:#"category_image"] objectAtIndex: indexPath.row]];
NSLog(#"%#",dict);
NSString *temps= [NSString stringWithFormat:#"%#",filePath];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:paths]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(#"%#",response);
UIImage *imgage = [[UIImage alloc] initWithData:data];
_imageView.image=[[UIImage alloc] initWithData:imgage];
_imageView.image=[[NSData alloc]initWithData:data];
//imageView.contentMode = UIViewContentModeScaleAspectFill;
// _imageView.clipsToBounds = YES;
//imageView.tag = IMAGE_VIEW_TAG;
}];
if (cell.selected) {
cell.backgroundColor = [UIColor blueColor]; // highlight selection
}
else
{
cell.backgroundColor = [UIColor redColor]; // Default color
}
return cell;
}
Register your custom cell in viewDidLoad method
[yourCollectionView registerNib:[UINib nibWithNibName:#"CustomCell" bundle:nil] forCellWithReuseIdentifier:#"your Cell Identifier"];
And then you will write on cellForItemAtIndexPath method
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"your Cell Identifier";
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
NSDictionary *dict = imageAry[indexPath.row];
//SdWebimage to load image
[cell.imgUser sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/%#", baseUrl, dict[#"imageName"]]];
return cell;
}
Download SDWebimageImageLoader to use of async image downloader with cache support.
NSString *path = [NSString stringWithFormat:#"%#/%#", baseUrl, imageName];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *imgage = [[UIImage alloc] initWithData:data];
pass this image to your imageview.
As you are loading images from server, you can also use SDWebImage for image caching purpose.
https://github.com/rs/SDWebImage

Xcode table view lag when scrolling

(void)bilgileriYukle
{
NSMutableArray *yemekIsimleri = [[NSMutableArray alloc] init];
NSMutableArray *resimIsimleri = [[NSMutableArray alloc] init];
NSURL *myURL = [[NSURL alloc]initWithString:#"http://www.sevgilezzeti.com/WebServices/tarifler.php"];
NSData *myData = [[NSData alloc]initWithContentsOfURL:myURL];
if (myData == nil)
{
NSLog(#"INTERNET YOK YADA VERI CEKEMEDI");
}
else
{
NSLog(#"INTERNET VAR VERI CEKILDI");
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:myData options:kNilOptions error:nil];
for (id element in jsonArray)
{
NSString *durum = [element objectForKey:#"durum"];
if([durum isEqualToString:#"1"])
{
[yemekIsimleri addObject:[element objectForKey:#"yemekadi"]];
NSString *gelenYemekAdi =[element objectForKey:#"kapakresmi"];
NSString *imagePathKapak = #"http://sevgilezzeti.com/Admin/yemekresimkapak/";
combined = [NSString stringWithFormat:#"%#%#", imagePathKapak, gelenYemekAdi];
[resimIsimleri addObject:combined];
}
}
}
_TarifAdi=yemekIsimleri;
_ResimAdi=resimIsimleri;
}
///////////////////////////////////////////////////////////////////////////////////////
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
NSUInteger row = [indexPath row];
cell.TitleLabel.text = _TarifAdi[row];
NSCache *_imageCache;
UIImage *image = [_imageCache objectForKey:#"DenemeRes"];
if (image == nil) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[row]]];
image = [UIImage imageWithData:data];
[_imageCache setObject:image forKey:#"DenemeRes"];
}
cell.ThumbImage.image = image;
return cell;
}
I can get images from URL and can see images but when I scroll the table view, it's very slow and lagging. How can I fix this problem ?
It's pretty easy and straightforward to load images synchronously in table view cells, however it's evil, because it would cause the lag when you scroll it, because it's actually trying to load and display the images as you're scrolling.
Therefore, you must avoid loading images synchronously, but asynchronously instead, using a different thread other than the main thread, so that the scrolling and loading + displaying images can be done dependently, avoiding any kind of lag.
This is possibly a duplicate question, since it's already been asked and there are tutorials out there, but since I myself always had a problem with this on my first iOS app and found it very confusing, I'm posting the answer here, hoping it's helpful.
Try adding something like this to your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:
// Get the filename to load.
NSString *imageFilename = [imageArray objectAtIndex:[indexPath row]];
NSString *imagePath = [imageFolder stringByAppendingPathComponent:imageFilename];
[[cell textLabel] setText:imageFilename];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
dispatch_sync(dispatch_get_main_queue(), ^{
[[cell imageView] setImage:image];
[cell setNeedsLayout];
});
});
dataWithContentsOfURL is blocking your main thread, that'w why the table is acting like it is. You should load images in back thread so that the main thread can handle UI without interruptions
NSURL *url = [NSURL URLWithString:link];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url cachePolicy:0 timeoutInterval:kTimeoutInterval];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
UIImage *image = [[UIImage alloc] initWithData:self.activeDownload];
// set to ImageView
cell.ThumbImage.image = image;
}];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
cell.tag = indexPath.row;
cell.imageView.image = nil;
// Rounded Rect for cell image
CALayer *cellImageLayer = cell.imageView.layer;
[cellImageLayer setCornerRadius:35];
[cellImageLayer setMasksToBounds:YES];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^(void) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[indexPath.row]]];
UIImage *image = [[UIImage alloc] initWithData:data];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
CGSize itemSize = CGSizeMake(70, 70);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[cell setNeedsLayout];
}
});
}
});
cell.TitleLabel.text = _TarifAdi[indexPath.row];
return cell;
}

Cell text overlapping when scrolling in UITableView Xcode iOS

Everytime I start scrolling in the tableView the subtitleLabel text keeps overlapping each other in every row. I've tried for the last 4 hours every single search on the Internet for this problem I have clicked and tried.
Here is my ViewController.m:
#interface ANViewController()
{
NSMutableArray *TitleLabel;
NSMutableArray *SubtitleLabel;
NSMutableArray *AvatarImages;
}
#end
#implementation ANViewController
#synthesize thetableview;
- (void)viewDidLoad
{
[super viewDidLoad];
self.thetableview.delegate = self;
self.thetableview.dataSource = self;
TitleLabel = [NSMutableArray array];
SubtitleLabel = [NSMutableArray array];
AvatarImages = [NSMutableArray array];
__block NSArray *posts;
__block NSData *allNewsData = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0ul);
dispatch_async(queue, ^{
allNewsData = [NSData dataWithContentsOfURL:[NSURL URLWithString: API_URL]];
NSError *error;
NSMutableDictionary *allNews = [NSJSONSerialization JSONObjectWithData:allNewsData options:NSJSONReadingMutableContainers error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
posts = allNews[#"data"];
for (NSDictionary *newsPost in posts) {
[TitleLabel addObject:newsPost[#"title"]];
[SubtitleLabel addObject:newsPost[#"post_message"]];
NSString *avatarUrl = AVATAR_URL;
NSString *avatarExt = #".jpg";
[AvatarImages addObject:[NSString stringWithFormat:#"%#%#%#", avatarUrl, newsPost[#"user_id"], avatarExt]];
}
}
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(#"THIS IS THE MAIN THREAD...");
[self.thetableview reloadData];
});
});
NSURL *url = [NSURL URLWithString: WEBSITE_URL];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
long count = TitleLabel.count;
if(count == 0){
count = 1;
}
return count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier;
ANTableViewCell *Cell;
if(TitleLabel.count == 0){
NSLog(#"Did with no news");
CellIdentifier = #"Cell_NoNews";
Cell = [thetableview dequeueReusableCellWithIdentifier:CellIdentifier];
if (Cell == nil) {
Cell = [[ANTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Cell.noNewsLabel.text = #"No news to display!";
}else{
NSLog(#"Did with news");
CellIdentifier = #"Cell";
Cell = [thetableview dequeueReusableCellWithIdentifier:CellIdentifier];
if (Cell == nil) {
Cell = [[ANTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Cell.TitleLabel.text = [TitleLabel objectAtIndex:indexPath.row];
Cell.SubtitleLabel.text = [SubtitleLabel objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:[AvatarImages objectAtIndex:indexPath.row]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
Cell.AvatarImage.image = img;
}
return Cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Just change UITableViewCellStyleSubtitle for UITableViewCellStyleDefault, and you need an asynchronous connection instead of a synchronous like you're doing: NSData *allNewsData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:API_URL]]; in your viewDidLoad method that is blocking your main thread.
You can adapt this code to your need, in order to download it on the background:
__block NSData *allNewsData = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
allNewsData = [NSData dataWithContentsOfURL:[NSURL URLWithString: API_URL]];
NSURL *url = [NSURL URLWithString: WEBSITE_URL];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(#"THIS IS THE MAIN THREAD...");
[self.thetableview reloadData];
});
});

NSOperationQueue Issue

I have a code that i used as a image downloder in ios 6 but when i use same code in different application that used ios 5 it gives me error NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance hear is the code that i am using
[self.imageDownloadingQueue addOperationWithBlock:^{
NSURL *imageUrl = [NSURL URLWithString:ImageURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *images = nil;
if (imageData)
images = [UIImage imageWithData:imageData];
if (images){
[self.imageCache setObject:images forKey:ImageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// make sure the cell is still visible
imageV.image = images;
}];
}
}];
Can anybody tell me what i am doing wrong coz this code is help me a lot when downloading image separately. Thank you
PS Whole function that i am using
-(void) setScrollView:(UIScrollView *)scrollview :(NSArray *)contentArray{
int x = 0;
int i = 0;
NSString *ImageURL=#"http://www.online-image-editor.com/styles/2013/images/example_image.png";
for(NSDictionary *str in contentArray){
UIImageView *imageV = [[UIImageView alloc ] initWithFrame:CGRectMake(x, 0, 200,125)];
#try {
ImageURL = [str objectForKey:#"image"];
}
#catch (NSException * e) {
NSLog(#"Exception: %#", [e description]);
}
imageV.userInteractionEnabled = YES;
ImageTapGesture *singleTap = [[ImageTapGesture alloc] initWithTarget:self action:#selector(tapDetectedMain:)];
singleTap.newItem = str;
singleTap.currentItem = i ;
singleTap.numberOfTapsRequired = 1;
[imageV addGestureRecognizer:singleTap];
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(x,125,200,20)];
[title setFont:[UIFont systemFontOfSize:11]];
title.numberOfLines = 2;
title.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[title setBackgroundColor:[UIColor blackColor]];
[title setTextColor:[UIColor whiteColor]];
title.text = [NSString stringWithFormat:#" %#",[str objectForKey:#"title"]];
x += title.frame.size.width+2;
UIImage *cachedImage = [self.imageCache objectForKey:ImageURL];
if (cachedImage){
imageV.image = cachedImage;
}
else{
imageV.image = [UIImage imageNamed:#"vdo.png"];
[self.imageDownloadingQueue addOperationWithBlock:^{
NSURL *imageUrl = [NSURL URLWithString:ImageURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *images = nil;
if (imageData)
images = [UIImage imageWithData:imageData];
if (images){
[self.imageCache setObject:images forKey:ImageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// make sure the cell is still visible
imageV.image = images;
}];
}
}];
}
[scrollview addSubview:imageV];
[scrollview addSubview:title];
}
scrollview.contentSize = CGSizeMake(x, scrollview.frame.size.height);
i++;
}
You should definitely check the ImageURL you are sending into the operation. It seems, this ImageURL is [NSNull null].
If it is a local variable, is it declared as __block NSString *ImageUrl?
pls try this code:
[self.imageDownloadingQueue addOperationWithBlock:^{
NSURL *imageUrl ;
if((ImageURL!=nil)&&(![ImageURL isKindOfClass:[NSNull class]]))
{
imageUrl= [NSURL URLWithString:ImageURL];
}
NSData *imageData;
if((imageUrl!=nil)&&(![imageUrl isKindOfClass:[NSNull class]]))
{
imageData = [NSData dataWithContentsOfURL:imageUrl];
}
UIImage *images = nil;
if((imageData!=nil)&&(![imageData isKindOfClass:[NSNull class]]))
images = [UIImage imageWithData:imageData];
if((images!=nil)&&(![images isKindOfClass:[NSNull class]]))
{
[self.imageCache setObject:images forKey:ImageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// make sure the cell is still visible
imageV.image = images;
}];
}
}];
Hope this will help you.

How will I stop repeating the loading of images in my table view?

Here is my code displaying images from server. After the image is loaded, when you scroll down and then back, the image disappears and there's another delay before it's loaded again.
dispatch_async(kBgQueue, ^{
NSString *profileImageStr = [[displayItems objectAtIndex:indexPath.row] objectForKey:#"image_url"];
NSURL* profileImgURL = [NSURL URLWithString:profileImageStr];
NSData *profileImgData = [NSData dataWithContentsOfURL:profileImgURL];
NSString *postPhotoStr = [[displayItems objectAtIndex:indexPath.row] objectForKey:#"image_url"];
NSURL *postImgURL = [NSURL URLWithString:postPhotoStr];
NSData *postImageData = [NSData dataWithContentsOfURL:postImgURL];
dispatch_async(dispatch_get_main_queue(), ^{
if (postImageData && profileImgData != nil) {
cell.thumbnailImg.image = [UIImage imageWithData:profileImgData];
cell.bgImgView.image = [UIImage imageWithData:postImageData];
}else
{
cell.thumbnailImg.image = [UIImage imageNamed:#"noimage.jpg"];
cell.bgImgView.image = [UIImage imageNamed:#"noimage.jpg"];
}
});
}
);
return cell;
I think you need to implement cache for image. Store image in NSCache.
//instance
NSCache *imageCache;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *simpleTableIdentifier=nil;
if([objRepresentative.team count]>0)
{
simpleTableIdentifier=[NSString stringWithFormat:#"%#",[objRepresentative.employeeID objectAtIndex:indexPath.row]];
}
else
simpleTableIdentifier = #"ContactTableCell";
ContactTableCell *cell = (ContactTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ContactTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
NSString *photoString=[NSString stringWithFormat:#"http://www.foo.com/%#",[searchPhoto objectAtIndex:indexPath.row]];
UIImage *image = [imageCache objectForKey:photoString];
if (image)
{
cell.ProfilePicture.image=image;
}
else
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:[photoString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:url]];
if(image)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *small = [self imageWithImage:image scaledToSize:CGSizeMake(100, 100)];
cell.ProfilePicture.image=small;
});
[imageCache setObject:image forKey:photoString];
}
else
cell.ProfilePicture.image=[UIImage imageNamed:#"noPicture.png"];
});
}
}
return cell;
}

Resources