uicollection view reusable cell images are reloading while scrolling - iphone

hello am using UICollectionView for showing images in my iphone application but when i scrolling the view the loaded images are gone and loading images again this is because of "dequeueReusableCellWithReuseIdentifier"
and this is my code
static NSString * const kCellReuseIdentifier = #"collectionViewCell";
[self.collectionViewPack registerNib:[UINib nibWithNibName:#"CollectionViewItem" bundle:nil] forCellWithReuseIdentifier:kCellReuseIdentifier];
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellReuseIdentifier forIndexPath:indexPath];
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];
UIImageView *icon=(UIImageView *)[cell viewWithTag:101];
// [titleLabel setText:[NSString stringWithFormat:#"%d",indexPath.row]];
[titleLabel setText:[NSString stringWithFormat:#"%#",[arrayImages objectAtIndex:indexPath.row]]];
icon.image =[UIImage imageNamed:#"loading-1.png"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *imagePath = [NSString stringWithFormat:#"%#", [test.arrImages objectAtIndex:indexPath.row]];
NSURL *imageUrl = [NSURL URLWithString:imagePath];
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *image = nil;
if (imageData){
image = [[UIImage alloc] initWithData:imageData];
icon.image = image;
}
[image release];
});
return cell;
}
please help me out from this.

I guess you need to add some image cache to your code, I recommend you to use AFNetworking,
you can easily do:
import "UIImageView+AFNetworking.h"
......
[cell.imageView setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:#"default"]];
And, it has an internal Cache that will help :D
and for your code... try by adding this in your block
dispatch_async(dispatch_get_main_queue(), ^{
icon.image = image;
});

change kCellReuseIdentifier to dynamic
static NSString * const kCellReuseIdentifier = #"collectionViewCell";
to
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString * kCellReuseIdentifier =
[NSString stringWithFormat:#"collectionViewCell%d",indexPath.row];
It may work

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// Setup cell identifier
static NSString *cellIdentifier = #"put you viewController here";
/* this block to use nib-based cells */
UICollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
forIndexPath:indexPath];
/* end of nib-based cell block */
/* this block to use subclass-based cells */
yourviewController *cell =
(CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
forIndexPath:indexPath];

Related

Set UITableview cell image from url in iOS

I am setting image on UITableViewCell using image url ,but the images doesn't get load unless i scrolls the UITableView.Here is the code that i have been using,i got to know about SDWeb Image library to download images from url,but i does;t want to use any library.Please tell me what aim doing wrong in this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSDictionary *dictCard=[cardsDetailsArray objectAtIndex:indexPath.row];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:10];
UILabel *dateLabel = (UILabel *)[cell viewWithTag:11];
UIImageView *cellImage=(UIImageView *)[cell viewWithTag:0];
CGSize firstSize=CGSizeZero;
if([[dictCard objectForKey:#"orientation"]isEqualToString:#"1"]){
[cellImage setFrame:CGRectMake(0, 0, 75, 68)];
firstSize=CGSizeMake(75,68);
}
if([[dictCard objectForKey:#"orientation"]isEqualToString:#"0"]){
[cellImage setFrame:CGRectMake(0, 0, 107, 72)];
firstSize=CGSizeMake(107,72);
}
[cellImage setBackgroundColor:[UIColor clearColor]];
NSString *string=[dictCard objectForKey:#"email_sent"];
NSArray *items = [string componentsSeparatedByString:#","];
dateLabel.text=[dictCard objectForKey:#"date"];
nameLabel.text=[NSString stringWithFormat:#"Sent to %d People",[items count]];
NSURL* url = [NSURL URLWithString:(NSString *) [dictCard objectForKey:#"card_thumbnail"]];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
UIImage* image = [[UIImage alloc] initWithData:data];
//i am scaling the image here
UIImage *imageScale=[self imageWithImage:image scaledToSize:firstSize];
[cellImage setImage:imageScale];
}
}];
return cell;
}
I have also added [__tableViewDraft reloadData];after setting the cell image but due to this my cell keeps on changing its cell image.
Once the image has been downloaded, you need to ask iOS to refresh the cell. Check out reloadRowsAtIndexPaths:withRowAnimation:, among others.
Typically you might have have cells backed by CoreData objects and download and save the image to the managed object. You'd then have an NSFetchedResultsControllerDelegate trigger an update when the managed object changes, refreshing the row.

IOS: Collection view image position changing

I'm using UICollectionView to display images which are loading from the device photo gallery. I'm using Asset Library to load the images. When I'm scrolling the UICollectionView, images are changing their positions inside the collection view (not duplicating). Therefore when I clicked on an image, different image is loading. Any help?
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *GalleryImageView = (UIImageView *)[cell viewWithTag:100];
url=#"";
Document* doc = [galleryImages objectAtIndex:indexPath.row];
GalleryImageView.contentMode = UIViewContentModeScaleAspectFill;
url = doc.path;
NSLog(#"%#",url);
NSURL *referenceURL = [NSURL URLWithString:url];
__block UIImage *returnValue = nil;
[library assetForURL:referenceURL resultBlock:^(ALAsset *asset)
{
returnValue = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]];
GalleryImageView.image = returnValue;
returnValue = nil;
documentID= [dbutil getDocumentIDbyPath:url];
GalleryImageView.tag = documentID;
}
failureBlock:^(NSError *error)
{
NSLog(#"error : %#", error);
}];
return cell;
}

Image lazy loading in table view

I want to use lazy loading of images concept in my table view. My array of image rul string is ( MSMutableArray ) "images". How can I implement this in cellForRowAtIndexPath.
It looks like:
-(UITableViewCell *) tableView:(UITableView *)AtableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[searchtable dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
cell.textLabel.font=[UIFont systemFontOfSize:12];
cell.imageView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[appSmallLogos objectAtIndex:indexPath.row]]]];
cell.detailTextLabel.text=[appReleaseDates objectAtIndex:indexPath.row];
}
return cell;
}
Try this code :
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.frame = CGRectMake(your bounds);
[cell addSubview:indicator];
[indicator bringSubviewToFront:self.view];
[indicator startAnimating];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
//This is what you will load lazily
NSString *u=[NSString stringWithContentsOfFile:r.url encoding:NSUTF8StringEncoding error:nil];
NSURL *imageURL=url;
NSData *image=[NSData dataWithContentsOfURL:imageURL];
dispatch_sync(dispatch_get_main_queue(), ^{
CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image=[UIImage imageWithData:image];
[cell setNeedsLayout];
[indicator stopAnimating];
});
});
cell.cellDescription.text=r.url;// this is which you want to add in first time.
I am not sure but try it.
You can use the SDWebImage library, the library will download and cache the image asynchronously. by passing the url to it as argument
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.textLabel.text = #"My Text";
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TableCellLayout *cell = (TableCellLayout *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[TableCellLayout alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.cellName = [[array valueForKey:#"name"] objectAtIndex:indexPath.row];
cell.cellImage = [UIImage imageNamed:#"placeholder.png"]; // add a placeholder
NSString *imageURL = [[array valueForKey:#"imageLink"] objectAtIndex:indexPath.row];
NSURL *theURL = [NSURL URLWithString:imageURL];
if (asynchronousImageLoader == nil){
asynchronousImageLoader = [[AsynchronousImages alloc] init];
}
[asynchronousImageLoader loadImageFromURL:theURL];
cell.cellImage = asynchronousImageLoader.image;
return cell;
}
I finally managed to do it setting the image with:
– performSelectorOnMainThread:withObject:waitUntilDone:
After the image is downloaded

ASIHTTPRequest is not updating the DownloadProgress Delegate

I am using ASIHTTPRequest to download a file locally to the iDevice.
My download code is as follows
ASIHTTPRequest *download = [ASIHTTPRequest requestWithURL: videoUrl];
[download setCompletionBlock:^{
NSLog(#"Download Success");
// other code
}];
[download setFailedBlock:^{
NSLog(#"Download Failed");
// other code
}];
[download setDownloadProgressDelegate: [item progressDelegate]];
[download startAsynchronous];
NSLog(#"Start Download of %#", [item name]);
The object item holds a reference to a UIProgressView It is show on the screen but never updated.
In an attempt to debug, I subclassed UIProgressView and added the following log
- (void)setProgress:(float)newProgress {
NSLog(#"Current Progress : %f", newProgress);
[super setProgress: newProgress];
}
My Console now shows the progress going from 0.0 to 1.0 over ~50 iterations (nice!) but the uiProgressView doesnt change and at the end the NSLog show 0.5 the default setting for the progress view.
Anyone have an Idea what is happening?
EDIT
UIProgressView is accessed with this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
id progressView = [cell viewWithTag:VideoDetailProgressView];
[VideoDownloadManager queueDownloadOfVideo:video progressDelegate: progressView];
}
I have stepped through and watched it appears to keep the correct reference to the UIProgressView throughout
Edit
TableView Methods
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *detailCellIdentifier = #"VideoDetailCell";
static NSString *categoryCellIdentifier = #"VideoCategoryCell";
UITableViewCell *cell = nil;
bool isCategorical = [[self.videoList objectAtIndex: indexPath.row] objectForKey:#"parentName"];
if(isCategorical)
{
cell = [tableView dequeueReusableCellWithIdentifier:categoryCellIdentifier];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:detailCellIdentifier];
}
if (cell == nil && !isCategorical) {
[[NSBundle mainBundle] loadNibNamed:#"VideoDetailCell" owner:self options:nil];
cell = self.videoDetailCell;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5.0, 10.0, 46.0, 46.0)];
[cell addSubview:imageView];
imageView.hidden = !self.canEdit;
imageView.tag = VideoDetailsFavoriteButton;
[imageView release];
self.videoDetailCell = nil;
}
else if(cell == nil && isCategorical)
{
//Different cell
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:categoryCellIdentifier] autorelease];
}
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}
// Display customization
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *object = [self.videoList objectAtIndex:indexPath.row];
bool isCategorical = [[self.videoList objectAtIndex: indexPath.row] objectForKey:#"parentName"];
if(isCategorical) {
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = [object objectForKey:#"name"];
NSUInteger videoCount = [[Videos sharedVideos] countById: [object objectForKey:#"name"]];
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.text = [NSString stringWithFormat: #"%d videos", videoCount];
}
else
{
[[cell viewWithTag:VideoDetailCellTitle] setValue:[object objectForKey:#"name"] forKey:#"text"];
[[cell viewWithTag:VideoDetailCellSubtitle] setValue:[object objectForKey:#"dateAdded"] forKey:#"text"];
[[cell viewWithTag:VideoDetailCellDuration] setValue:[object objectForKey:#"duration"] forKey:#"text"];
UIHTTPImageView *asyncImage = (UIHTTPImageView *)[cell viewWithTag:VideoDetailCellImage];
NSURL *thumbUrl = [NSURL URLWithString:[NSString stringWithFormat: #"%#%#", kRootUrlPath, [object objectForKey:#"image"]]];
[asyncImage setImageWithURL:thumbUrl placeholderImage: [UIImage imageNamed: kLoadingImage]];
asyncImage.clipsToBounds = YES;
UIImageView *editButton = (UIImageView *)[cell viewWithTag:VideoDetailsFavoriteButton];
if ([VideoDownloadManager isQueued: [object objectForKey: #"name"]]) {
[[cell viewWithTag:VideoDetailCellSubtitle] setHidden:YES];
[[cell viewWithTag:VideoDetailProgressView] setHidden:NO];
} else {
[[cell viewWithTag:VideoDetailCellSubtitle] setHidden:NO];
[[cell viewWithTag:VideoDetailProgressView] setHidden:YES];
}
if ([VideoDownloadManager isFavorites: [object objectForKey: #"name"]] || [VideoDownloadManager isQueued: [object objectForKey: #"name"]]) {
editButton.image = [UIImage imageNamed: kFavoritesHighlighted];
} else {
editButton.image = [UIImage imageNamed: kFavoritesEmpty];
}
}
}
Can you check if the update is made in the main thread? (it should be the case if you're using the latest version of ASIHTTPRequest)
NSLog(#"Current Progress : %f (main thread=%d)", newProgress, [NSThread isMainThread]);
If it doesn't help, can you show the code that is using the UIProgressView in the view?
Thanks for everyones help. You guys guided me to then answer. My cell was not correctly being assigned a reuseIdentifier
this was causing the whole issue.

how to set image in uitable view

I download some images using an NSThread. When all the images are downloaded, I have to put them in cell.myimageview. Give me the solution for setting an image in a user-defined method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
TableCell *cell = (TableCell *)[TableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TableCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSString *bedsbaths=[NSString stringWithFormat:#"Beds:%# Baths:%#",[[AppDeleget.statuses valueForKey:#"beds"] objectAtIndex:indexPath.row],[[AppDeleget.statuses valueForKey:#"baths"] objectAtIndex:indexPath.row]];
cell.mlsno.text=[[AppDeleget.statuses valueForKey:#"mlsno"] objectAtIndex:indexPath.row];
cell.price.text=[[AppDeleget.statuses valueForKey:#"price"] objectAtIndex:indexPath.row];
cell.address.text=[[AppDeleget.statuses valueForKey:#"address"] objectAtIndex:indexPath.row];
cell.bedsbaths.text=bedsbaths;
cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
-(void)LoadImage
{
for(int x=0;x<[ListPhotos count];x++)
{
NSData *imageData =[ListPhotos objectAtIndex:x];
id path = imageData;
NSURL *url = [NSURL URLWithString:path];
NSLog(#"%#",url);
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
[self performSelectorOnMainThread:#selector(downloadDone:) withObject:img waitUntilDone:NO];
}
}
-(void)downloadDone:(UIImage*)img {
// I have to set the cell here. How?
cell.myimageView.image=img
}
In -(void)LoadImage
Store the img in a NSArray.
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath , code as
cell.myimageView.image=[imgArray objectAtIndex:indexPath.row];
Assign the delegate and datasource of tableview as,
-(void)downloadDone:(UIImage*)img {
self.tableView.delegate=self;
self.tableView.datasource=self;
}