I am using array of url's for images to load in collection view. Images are changing while scrolling the collection view. How to fix this issue?
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"RecentProductCell";
RecentProductCell *recentCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
recentCell.recentProductImg.image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSString *imageurl = [[latestProducts valueForKey:#"image"]objectAtIndex:indexPath.item];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl]];
dispatch_sync(dispatch_get_main_queue(), ^{
recentCell.recentProductImg.image = [UIImage imageWithData:imageData];
});
});
}
Replace dispatch_sync(dispatch_get_main_queue(), ^{
recentCell.recentProductImg.image = [UIImage imageWithData:imageData];
});
with
dispatch_sync(dispatch_get_main_queue(), ^{
if ( imageData )
{
UIImage *urlImage = [[UIImage alloc] initWithData:imageData];
RecentProductCell *recentCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
if (recentCell)
[recentCell.recentProductImg setImage:urlImage];
}
});
Let me know if this works for you.
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSString *imageurl = [[latestProducts valueForKey:#"image"]objectAtIndex:indexPath.item];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.imageView.image = image;
[cell setNeedsLayout];
}
});
}
});
Write this code in cellForRowAtIndexPath method of collectionView
Related
NSString *url = [NSString stringWithFormat:#"%#",[enclosureUrlArray objectAtIndex:indexPath.row]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
([self.tableView cellForRowAtIndexPath:indexPath]);
dispatch_async(dispatch_get_main_queue(), ^{
cell.tag = indexPath.row;
UIImage *image = [UIImage imageWithData:imageData];
cell.IMGLabel.image = image;
[cell.IMGLabel setImage:image];
[cell.IMGLabel.layer setMasksToBounds:YES];
[cell.IMGLabel.layer setCornerRadius:2.5f];
[cell setNeedsLayout];
});
});
(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;
}
So i have problem...For me, Having the dispatch_async code within cellForRowAtIndexPath method is too clunky and messy for me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = #"myCellID";
myCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// someData - an array of dictionary for the tableview datasource
NSURL * imageURL = [NSURL URLWithString:someData[indexPath.row][#"photoURL"]];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
cell.myImageView.image = image;
});
});
}
So after a little research my solution to this was:
-(void)loadAsyncImage:(NSIndexPath *)indexPath{
NSURL * imageURL = [NSURL URLWithString:someData[indexPath.row][#"photoURL"] ];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *myImage = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
// _myTableView a property link from the interface builder
myCell * cell = (id)[_myTableView cellForRowAtIndexPath:indexPath];
cell.myImageView.image = myImage;
});
});
}
and then in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = #"myCellID";
myCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[self loadAsyncImage: indexPath];
}
To my surprise it works and is so much more cleaner...but... i dont know if this is the right way to do this. Is there a better approach to this issue? or is this ok?
How can i check web service with database if database have will show image in database but not its will show image from web service
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
BookCell *bookcell = [collectionView dequeueReusableCellWithReuseIdentifier:#"ReuseCell" forIndexPath:indexPath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *imageURL = [NSURL URLWithString:[[bookList objectAtIndex:indexPath.item]coverURL]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *bookPath2 = [NSString stringWithFormat:#"%#/assets/book/%#/cover.png",path,bookPath];
NSLog(#"bookpath2 = %#",bookPath2);
dispatch_async(dispatch_get_main_queue(), ^{
if ([db isDownloaded:bookName bookVersion:[bookVersion floatValue]]) {
[bookcell.bookCover setImage:image];
[bookcell.bookCover setAlpha:1.0f];
// or this [bookcell.bookCover setImage:[UIImage imageWithContentsOfFile:bookPath2]];
}
else{
[bookcell.bookCover setImage:image];
[bookcell.bookCover setAlpha:0.5f];
[bookcell.bookDetailLabel setHidden:NO];
[bookcell.bookDetailLabel setAlpha:1.0f];
}
});
});
return bookcell;
}
Advice me Please.
Help me Please.
I'm try this is work for me,Thanks! for any Idea
if (bookPath2 = [NSString stringWithFormat:#"%#/assets/book/%#/cover.png",path],[[bookList objectAtIndex:indexPath.item] bookPath] && bookPath2 != [NSString stringWithFormat:#"%#/assets/book/(null)/cover.png",path]) {
NSLog(#"++++++++++++++++++++++");
bookcell.bookCover.image = [UIImage imageWithContentsOfFile:bookPath2];
if (checkversion < checkNewversion) {
bookcell.bookDetailLabel.text = #"Update";
bookcell.bookDetailLabel.hidden = NO;
} else
{
bookcell.bookDetailLabel.hidden = YES;
}
}
else {
bookcell.bookCover.image = nil;
NSLog(#"-------------------------");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *imageURL = [NSURL URLWithString:[[bookList objectAtIndex:indexPath.item]coverURL]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
bookcell.bookDetailLabel.text = #"New";
bookcell.bookCover.image = [UIImage imageWithData:imageData];
bookcell.bookCover.alpha = 0.5f;
bookcell.bookDetailLabel.hidden = NO;
});
});
}
return bookcell;
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;
}