Some problems with SDWebImage - ios

When I used the method load image, after the image gets downloaded, it does not show until I select or scroll the cell, but if I don't set the placeholderImage to nil, it works well. I don't know what's wrong with. Here's my code:
[cell.imageView sd_setImageWithURL:(my url) placeholderImage:nil];
Some problems with SDWebImage

It's weird, but you can try [cell setNeedsLayout]; after you set the image to reload all the cell views.
I guess you have all the calls inside tableView:cellForRowAtIndexPath:

use completion block to change the image view.
[myImage sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:IMG_PLACEHOLDER] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {}];
use this in your project and try.

Maybe you can use another method to do this, as an example:
[_theImageView sd_setImageWithURL:[NSURL URLWithString:_imageUrl]]

Related

Dynamically modifying the height of cells in a UICollectionViewCell in Objective C

I need to make a Pinterest style newsfeed. I have created a collection view with 2 columns. I am downloading the photos async in cellForItemAtIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {
TFNewsObject *obj = [self.sortedDataSource objectAtIndex:indexPath.row];
[imageView sd_setImageWithURL:url placeholderImage:nil options:SDWebImageRefreshCached
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
obj.tfImage = image;
}];
return cell;
}
The problem is that I need to set the size of the cell in heightForItemAtIndexPath and there the image has not been downloaded yet because it did not enter cellForItemAtIndexPath yet. I am setting a fixed size of 100 for the height.
I need to somehow trigger heightForItemAtIndexPath after I've downloaded the image in cellforItemAtIndexPath.
Another thing that I've tried is downloading the image in heightForItemAtIndexPath synchronous and calculating the height after the image downloaded. In that manner it displays correctly with each cell with a different height depending on the image, but it takes forever to load all the images.
Is there a way to modify the cell's height after I've downloaded the image? Thanks!
Try this
[imageView sd_setImageWithURL:url placeholderImage:nil options:SDWebImageRefreshCached
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
obj.tfImage = image;
collectionView .reloadItems(at: [indexPath])
}];
In -setImageWithURLRequest:..., when the image loads it in a hash table so you should then call -reloadItemsAtIndexPaths: with the current image path. This will reload the cell and thus cause the CollectionView to check what size the cell should be.
Another solution that you can try is to invalidate the collection view layout when the image is downloaded.
- (UICollectionViewCell *)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {
TFNewsObject *obj = [self.sortedDataSource objectAtIndex:indexPath.row];
[imageView sd_setImageWithURL:url placeholderImage:nil options:SDWebImageRefreshCached
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
[self.collectionView.collectionViewLayout invalidateLayout];
}];
return cell;
}
After this return a appropriate size in the delegate method:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return /* size */;
}
I got into similar problem while i developed something similar to pinterest layout.
Even we had a lag while downloading images asynchronously and once the download is done refreshing cell by cell will blow away the user and will lead to UI jerks.
The solution which i could suggest is,
For example when the post is created with the image, Calculate the size (width and height) of the image and save it in the DB. So the size of the image is available before the image is downloaded or cached and we could scale the cell to the height of the image and display a default image and when the actual image is cached or downloaded it would silently replace the default image without any UI jerks.
If you are using services like cloudinary then you can avoid the pain of storing the image size (height and width). The cloudinary api will give you the height and width of the image.

Reusable TableViewCell loads an old image

I have a dynamic tableview that can be searched through with a search box, and if I load an image in a cell in the background and the search text changes, the object in the cell may also change, and sometimes an old image that was loading in the background will finish and display when it shouldn't. Not every image is loaded in the same way, but this is the method that causes the problem:
[self.CarImage sd_setImageWithURL:imageURL
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageurl){
[self.CarImage setAlpha:0.0];
[UIImageView animateWithDuration:.5 animations:^{
[self.CarImage setAlpha:1.0];
}];
}];
Any ideas would be appreciated
You need to do two things here
1) in prepareforresue method Cancel current downloading request
2) in prepareforresue method set image to nil
Hope this will fix your issue
Here the issue is, image is loaded from url after you have already reused the cell. You can store the url of the image, each and everytime the cell being reused the url of the images should be stored inside the custom cell class. Then inside the completion block check that the loaded image url and the stored image url are same or not using isEqual: method of NSURL. If they are same then everything is ok, cell is not being reused, otherwise the cell is been used for another row, then just dont set the image.
self.carImgUrl = imageURL;//here carImgUrl is a property which you gonna set everytime when the cell is being reused.
[self.CarImage sd_setImageWithURL:imageURL
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageurl){
if([imageurl isEqual:self.carImgUrl])
{
[self.CarImage setAlpha:0.0];
[UIImageView animateWithDuration:.5 animations:^{
[self.CarImage setAlpha:1.0];
}];
}
}];

Loading images of "Next" TableView Cell Asynchronously

So I am using SDWebImage to load images into the cells.
I want to preload images of the next few cells so that when the user scrolls, the image is already loaded.
Whats the ideal way to do this.
Current code -->
[cell.BGImage sd_setImageWithURL:[NSURL URLWithString:section.imageURL] placeholderImage:[UIImage imageNamed:#"PlaceholderF"]];
Ensuring that the current displayed image is kept at priority loading.
Any suggestions?
You can use SDWebImageDownloader method to download image before your cell load or in other controller. So it will cache image and when your cell load it will show immediately.
[[SDWebImageDownloader sharedDownloader]downloadImageWithURL:nil options:SDWebImageDownloaderContinueInBackground progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
}];
and you can set download image priority in LIFO manner using below code.
[[SDWebImageManager sharedManager].imageDownloader setExecutionOrder:SDWebImageDownloaderLIFOExecutionOrder];
Maybe this will help you.

UITableView cell autoresizes some image views fed by AFNetworking 2.0

I have UITableViewController with a basic cell. In my tableView: cellForRowAtIndexPath: method implementation I set the .imageView property of my cell to get the data from the Internet, using AFNetworking 2.0 category: UIImageView+AFNetworking.
if (p.avatarPhoto) {
[cell.imageView setImageWithURL:p.avatarPhoto placeholderImage:[UIImage imageNamed:#"photo_frame.png"]];
}
When I do it, my table rows are properly generated and image is displayed, however its size changes when I highlight the row or scroll (so the rows reappear), like on this screen capture: https://dl.dropboxusercontent.com/u/51630060/ScreenDemo-20131219-102840.mov
When I set the image to some bundled one, not one from the network, it works OK.
How should I set the image to have it working properly?
EDIT: The image I'm using for testing is this one: http://hollywoodvideo.com/wp-content/uploads/2013/08/avatar-whatshisface.jpg. Maybe it's the matter of the aspect ratio of this image?
I had very similar issue with AFNetworking 1 and I sorted it by create week reference to the cell and by called setNeedsDisplay. Please see belowe, it's AFNetworking 1 byt you can make it works for AFN.. 2.o:
__weak UITableViewCell *weakCell = cell;
[cell.imageView setImageWithURLRequest:[[NSURLRequest alloc] initWithURL:p.avatarPhoto]
placeholderImage:[UIImage imageNamed:#"photo_frame.png"]
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
weakCell.imageView.image = image;
[weakCell setNeedsLayout];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
}];

Is there any way to stop an image in a UIImageView from lazy loading with SDWebImage on iOS?

I'm using the following code to lazy load an image into my UIImageView:
[self.imv1 setImageWithURL:[NSURL URLWithString:myURL]
placeholderImage:[UIImage imageNamed:#"loading.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
// stuff here
}];
When a user touches a button, I want the lazy loading of this to STOP completely, so that no image gets loaded and the download of the image stops.
After I stop the lazy loading, I plan to load a different image into the same UIImageView.
Is this possible with SDWebImage?
Found out how to do it. I just needed to call this:
[self.imv1 cancelCurrentImageLoad];

Resources