I'm using a UICollectionView and want to display images fetched from a server in it's cells. To do this I'm using UIImageView+AFNetworking. In my cellForItemAtIndexPath method I have the following code:
__weak CustomCollectionViewCell *weakCell = cell;
[cell.cellImageView setImageWithURLRequest:request
placeholderImage:placeholderImage
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.cellImageView.image = image;
[weakCell setNeedsLayout];
} failure:nil];
The placeholder always show, but sometimes the downloaded images aren't showing. Any ideas on how I could solve this?
I suspect the problem is that you're on a background thread when you try to set the image, whereas you should always perform UI operations on the main thread.
Try setting the image in the main thread with something like
__weak CustomCollectionViewCell *weakCell = cell;
[cell.cellImageView setImageWithURLRequest:request
placeholderImage:placeholderImage
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
dispatch_async(dispatch_get_main_queue(), ^{
weakCell.cellImageView.image = image;
});
} failure:nil];
I'm pretty sure that AFNetworking moves all the block execution on the main thread, I'm just wondering if you are sure that those images are correctly downloaded.
Try to log the image size of the retuned image, and if it is present always use a failure block, maybe just printing the error.
Something like that:
typeof(self) __weak weakCell = cell; //but you don't need in that scenario
[cell.cellImageView setImageWithURLRequest:request
placeholderImage:placeholderImage
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
NSLog(#"Image %# scale %f", NSStringFromCGSize(image.size), image.scale);
weakCell.cellImageView.image = image;
[weakCell setNeedsLayout];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"Error %#",error.localizedDescription);
}];
Solution for you question
SDWebImage
You just need to #import <SDWebImage/UIImageView+WebCache.h> to your project, and you can define also the placeholder when image is being downloaded with just this code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyCell"
forIndexPath:indexPath];
DLog(#"url at index %d : %#", indexPath.row, ((MyObject *)[self.list.array objectAtIndex:indexPath.row]).imageUrl);
MyObject *object = (MyObject *)[self.list.array objectAtIndex:indexPath.row];
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
return cell;
}
It also cache downloaded images and gives you great performance.
Hope it will help you!
After downloading the images, I replaced
[self.myCollectionView reloadData]
with
[self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
then refresh and it works well, you can try it.
Related
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];
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;
}
I am using table view to show a list of data. Each custom table cell has a back ground image coming from JSON. I use AFNetworking framework to download those image. But table view scrolling is not smooth. I create those cells using .xib file.
static NSString *CellIdentifire=#"CellId";
NSMutableDictionary *murDic=[matchListarry objectAtIndex:indexPath.row];
TTTCellFormatchList *matchListcell;
matchListcell=(TTTCellFormatchList *)[tableView dequeueReusableCellWithIdentifier:CellIdentifire];
if (matchListcell==nil)
{
NSArray *CellNib=[[NSBundle mainBundle] loadNibNamed:#"TTTCellFormatchListcontroller" owner:self options:nil];
matchListcell=(TTTCellFormatchList *)[CellNib objectAtIndex:0];
}
UIView *MainView=(UIView *)[matchListcell.contentView viewWithTag:101];
UIActivityIndicatorView *Spinner=(UIActivityIndicatorView *)[MainView viewWithTag:93];
//Clearing The back Ground
matchListcell.backgroundColor=[UIColor clearColor];
//Downlod back ground image in block and background thread
NSString *BackgroundImageStgring=[murDic valueForKey:#"MatchImage"];
UIImageView *BackgrounImage=(UIImageView *)[matchListcell.contentView viewWithTag:100];
NSURLRequest *request_img = [NSURLRequest requestWithURL:[NSURL URLWithString:BackgroundImageStgring]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request_img, imageProcessingBlock:nil, success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image)
{
if(image!=nil)
{
image=[image blurredImageWithRadius:2 iterations:1 tintColor:[UIColor darkGrayColor]];
[BackgrounImage setImage:image];
[Spinner stopAnimating];
[Spinner setHidden:YES];
}
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
[[UIImage imageNamed:#"picture.png"] applyLightEffect];
[BackgrounImage setImage:[UIImage imageNamed:#"picture.png"]];
NSLog(#"Error %#",error);
}];
[operation start];
// call background queue for dynamic loading of data
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// load your dynamic data here
// call main queue here
dispatch_async(dispatch_get_main_queue(), ^{
// after loading data in background. use your downloaded data here.
});
});
Custom UITableView with UITextview is not scrolling smoothly in ios device
In my method cellForItemAtIndexPath i have this code:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:coverURL] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {
RRRBigItemCell *cell = (RRRBigItemCell *)[collectionView cellForItemAtIndexPath:indexPath];
if (cell) {
RRRImageView *coverView = (RRRImageView *)[cell viewWithTag:COVER_TAG];
coverView.image = image;
}
}];
When i launch application and i scroll down then everything is ok. But when i scroll up than cell which were already displayed don't have loaded images (cell == nil). And if i again scroll down the problem remains for already displayed cells, only new ones have loaded images.
Any idea what i'm doing wrong?
#pawan is correct, that would be simplest way to implement SDWebImage. It's basically a category of UIImage, so simply use the category methods (setImageWithURL).
A couple of other points since you asked;
In your code, you should be setting the coverImage.image on the main thread, not in the background.
It's good practice to check if the Cell is visible, or there is little point in displaying the content.
It's good practice to create a weak reference to the Collection view when accessing the cell to avoid circular references
so your code ) might be written as follows if you were insistent on doing it the way you have it (Using the category is the best and simplest way)
__weak myCollectionViewController *weakSelf = self;
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:coverURL] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {
dispatch_async(dispatch_get_main_queue(), ^{
if ([weakSelf.collectionView.indexPathsForVisibleItems containsObject:indexPath]) {
RRRBigItemCell *cell = (RRRBigItemCell *)[weakSelf.collectionView cellForItemAtIndexPath:indexPath];
RRRImageView *coverView = (RRRImageView *)[cell viewWithTag:COVER_TAG];
coverView.image = image;
};
});
}];
why dont you try this
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
reference SDWebImage
I am trying to set image in UICollectionViewCell, via collectionView:cellForItemAtIndexPath:. I am using AFNetworking Image Category UIImageView+AFNetworking.h method for loading image from cloud server.
The problem is that, I am always hitting failure block. When open the link in browser window, I can see the image.
Here is the sample code:
__weak UICollectionViewCell *blockcell = cell;
NSURL *imageUrl = [NSURL URLWithString:#"https://ec2-75-101-163-253.compute-1.amazonaws.com/static/icons/app-excel%402x.png"];
[cell.appImage setImageWithURLRequest:[NSURLRequest requestWithURL:imageUrl] placeholderImage:[UIImage imageNamed:#"file-gray.png"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
blockcell.appImage.image = image;
[blockcell setNeedsLayout];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"fail for %#",request.URL);
}];
There might be a simple/silly mistake. Can anyone help me.
Thanks in advance.