UIImageView Aspect to Fit not working when tableview scrolls - ios

I use the code below to scale images to my UIImageView. Everything is fine when the table loads first time. But when I scroll the tableview, all the image aspects became broken.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ProductCell" forIndexPath:indexPath];
[self configureCustomCell:(ProductsTableViewCell*)cell atIndexPath:indexPath];
return cell;
}
- (void)configureCustomCell:(ProductsTableViewCell*)cell atIndexPath:(NSIndexPath *)indexPath {
NSURL *url = [NSURL URLWithString:[[arr_products objectAtIndex:indexPath.section] productImage]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
__weak UITableViewCell *weakCell = cell;
[cell.productPhotoImage setImageWithURLRequest:request placeholderImage:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.imageView.image = image;
weakCell.imageView.contentMode = UIViewContentModeScaleAspectFit;
weakCell.imageView.clipsToBounds = YES;
weakCell.imageView.frame = CGRectMake(5, 5, 60, 60);
}
failure:nil];
}

If you want to get the image from the server and then load it on the cell tableviewcell won't upgrade properly,
you can use SDWebImage Library to load the image from server, Check this link SDWEbImage
If you want to add activity indicator check this https://github.com/JJSaccolo/UIActivityIndicator-for-SDWebImage
#import <SDWebImage/UIImageView+WebCache.h>
in cellForRowAtIndexPath
[weakCell.myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:#"mawgif-log.png"] options:SDWebImageRefreshCached usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

Related

asynchronous image downloading in tabelviewcell?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
TVcell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TVcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.titleLabel.text = [[[arrayData objectAtIndex:indexPath.row]valueForKey:#"title"]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.txtlabel.text = [[[arrayData objectAtIndex:indexPath.row] valueForKey:#"description"]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.tag = indexPath.row;
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[enclosureUrlArray objectAtIndex:indexPath.row]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.IMGLabel.image = image;
[cell setNeedsLayout];
}
});
}
});
return cell;
}
while i'm scrolling that same images are appearing on the cells,which cells im reusing.i used scroll view delegate also.im storing urls in enclosureUrlArray and i'm passing.
Put cell.IMGLabel.image = nil in your cellForRowAtIndexPath before downloading image, i.e. below cell.imageView.image = nil; this line.
Or set some place holder image (no image available kind of image to cell's image in interface builder), so if image is not downloaded then it will show this place holder image otherwise it will show downloaded image.
SDWebImage is good for this kind of case. It will cache the images so it will give better performance also. There is nothing wrong to use any good third party library.
By using SDWeb image:
#import <SDWebImage/UIImageView+WebCache.h>
...
- (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 sd_setImageWithURL: method to load the web image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.textLabel.text = #"My Text";
return cell;
}
You can also use NSURLSession as well,see this link
Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling
NSURL *url = [NSURL URLWithString:[enclosureUrlArray objectAtIndex:indexPath.row]];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
UIImage *image = [UIImage imageWithData:data];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
MyCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
updateCell.IMGLabel.image = image;
});
}
}
}];
[task resume];
works perfect for me..
with the help of sdwebimage you can show the image like this:-
NSString *string2 = [[businessListArray objectAtIndex:indexPath.row ]valueForKey:#"logo"];
NSURL *url1 = [NSURL URLWithString:
[NSString stringWithFormat:
#"%#%#",
#"http://dev-demo.info.bh-in-15./upload/post/",
string2]];
UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:301];
[imageView sd_setImageWithURL:url1
placeholderImage:[UIImage imageNamed:#"pocket.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
imageView.image = image;
}];

download image from URL string using UIImageView+AFNetworking.h

I have problem with download image from URL string. When I use this for download image and set in on imageView on view it works but now I have to set it on imageView on Cell.
I cannot put this on cellForRowAtIndexPath: method where I have access to imageView on cell.
__weak EditViewController *weakSelf = self;
[weakSelf.imageView setImageWithURLRequest:request placeholderImage:placeholderImage
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakSelf.imageView.image = image;
[self.tableView reloadData];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
[self prepareAndShowAlertView];
}];
I'll be glad for any help with this. Thanks in advance.
If you are not able to put your download to cellForRow:AtIndexPath: delegate method than you need to add #property (nonatomic, strong) UIImage *image; to your controller and when image is downloaded
...success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakSelf.imageView.image = image;
self.image = image;
[self.tableView reloadData];
}
and in cellForRow:AtIndexPath: setup your image
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
[cell.imageView setImage:self.image];
return cell;
}

Async Image Loading Performance

I am loading images in UITableViewCell receiving from url using below code, everything is working fine but the image load very slow in UITableViewCell and if i think as a user, it is not acceptable.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [checkData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger i =indexPath.row;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UIImageView propertyImage = (UIImageView *)[cell viewWithTag:10];
NSString *test = [[checkData objectAtIndex:i]valueForKey:#"image"];
CGRect frame=propertyImage.bounds;
AsyncImageView asyImage=[[AsyncImageView alloc] initWithFrame:frame];
[asyImage setImage:[UIImage imageNamed:#"loading.png"]];
self.urlForTesting=[NSURL URLWithString:test];
[asyImage loadImageFromURL:self.urlForTesting];
asyImage.imageURL =self.urlForTesting;
asyImage.contentMode = UIViewContentModeScaleToFill;
asyImage.layer.masksToBounds=YES;
[propertyImage addSubview:asyImage];
return cell;
}
Use AFNetworking Class & add additional two file to download from github "UIImageView+AFNetworking" and import in your project. then after add this code from "cellForRowAtIndexPath"
// Fetch Image from URL
NSURL *url = [NSURL URLWithString:[[checkData objectAtIndex:i]valueForKey:#"image"]];
[objWinner.actWinner startAnimating];
[objWinner.actWinner setHidden:NO];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[objWinner.imgwinner setImageWithURLRequest:req placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
[objWinner.actWinner stopAnimating]; // this is Activityindicator
[objWinner.actWinner setHidden:YES];
objWinner.imgwinner.image = image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
}];

cellForItemAtIndexPath is Changing Multiple Cells When Should Change One

I may be not understanding the reusing of cells behaviour by the UICollectionView but can someone tell me why two cells are having their properties changed in cellForItemAtIndexPath when it should just be the one cell.
Here's my code.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCollectionViewCell *cell = (PhotoCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:#"PhotoCollectionViewCell" forIndexPath:indexPath];
if (![[self.userPhotos objectAtIndex:indexPath.row] isEqualToString:#""]){
NSString *photoUrl = [self.userPhotos objectAtIndex:indexPath.row];
NSURL *imageURL = [NSURL URLWithString: photoUrl];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:imageURL];
[cell.photoImageView setImageWithURLRequest:imageRequest placeholderImage:[UIImage imageNamed:#"anImage"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
cell.photoImageView.image = image;
cell.photoImageView.frame = CGRectMake(0, 0, 100.0f,100.0f);
cell.photoImageView.contentMode = UIViewContentModeScaleAspectFit;
[cell.deleteImageView setFrame:CGRectMake(-4.0f,-4.0f,28.0f,28.0f)];
cell.deleteImageView.layer.cornerRadius = cell.deleteImageView.frame.size.width / 2;
[cell.deleteImageView setAlpha:0.8f];
cell.deleteImageView.layer.borderWidth = 1.0f;
cell.deleteImageView.layer.borderColor = [UIColor redColor].CGColor;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"%#",[error localizedDescription]);
}];
}else{
cell.photoImageView.image = [UIImage imageNamed:#"camera"];
cell.photoImageView.layer.borderWidth = 1.0f;
cell.photoImageView.layer.borderColor = [UIColor lightGrayColor].CGColor;
NSLog(#"setting alpha & hiding delete");
cell.photoImageView.alpha = 0.4f;
[cell.deleteImageView setHidden:YES];
}
The code in the else part is being executed on cells 2 and 6 for example when it should just be 6. Although the logging says it's just executed on 6
Any idea where I'm going wrong?
Thanks.

how to loading images using Asynchronous GCD For UITableviewcell/

I'm loading images for my uitableview asynchronously using GCD, but there is a problem - when scrolling down UITableview the images are dissappeared on top.And sometimes the images are not displayed in UITableviewcell. This is my code.please give me any idea.Is there any error in my code.Please help me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"identifier"];
}
image=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 80)];
[cell.contentView addSubview:image];
str=att.classimage;
url=#"My URL";
if(str!=nil){
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *imageStr=[url stringByAppendingString:str];
image.image = [UIImage imageNamed:imageStr];
});
});
image.image=[UIImage imageNamed:#"nav-bar-logo.png"];
}
return cell;
}
Before setting Image check if that cell is still in memory.
UITableViewCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
{
yourImageView.image = [imagePost fixOrientation];
}
I am doing similar thing, but Using NSURLConnection.
NSURL *postImage = [NSURL URLWithString:#"Your URL"];
NSMutableURLRequest *imageRequest = [[NSMutableURLRequest alloc]initWithURL:postImage cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
[imageRequest setHTTPMethod:#"GET"];
[NSURLConnection sendAsynchronousRequest:imageRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
imagePost = [UIImage imageWithData:data]; // UIImage Object
UITableViewCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
{
postImageView.image = [imagePost fixOrientation];// setting my ImageView
}
}];
Hope this will help you.
You can use AFNetworknig for showing images from remote URL.
get AFNetworking from here
just
#import "AFNetworking.h"
[imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeHolderImage"]];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
UIImageView *imageView =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 80)];
imageView.tag = 100;
[cell.contentView addSubview:imageView];
}
str=att.classimage;
url=#"My URL";
UIImageView *cellImageView = [cell.contentView viewWithTag:100];
cellImageView.image = nil;
if(str!=nil) {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSString *imageStr = [url stringByAppendingString:str];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageStr]]];
dispatch_async(dispatch_get_main_queue(), ^{
cellImageView.image = image;
});
});
}
return cell;
}

Resources