7

I want to show the imageview's background color till the download is in progress and if the download fails or image is not available then i want to show a placeholder image. How can i achieve this?

The main objective is to set the image later not during loading.

Thanks

Ankit Kumar Gupta
  • 3,994
  • 4
  • 31
  • 54
  • 1
    Not the required thing. I have used throughout imageView.sd_setImage(with: url ,placeholderImage: UIImage(named: "ico_placeholder")) But what it does is that it sets a placeholder image even during the load is in progress. I want to display the placeholder only if the load fails. – Ankit Kumar Gupta Feb 02 '17 at 07:40

6 Answers6

9

Solution for Swift 3 :

cell.imageView?.sd_setImage(with: url) { (image, error, cache, urls) in
            if (error != nil) {
                cell.imageView.image = UIImage(named: "ico_placeholder")
            } else {
                cell.imageView.image = image
            }
}

Solution for Objective C :

[cell.imageView sd_setImageWithURL:url
                  placeholderImage:nil
                         completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                                if (error) {
                                  self.imageView.image = [UIImage imageNamed:@"ico_placeholder"];
                                } else {
                                  self.imageView.image = image;
                                }
}];

Hope you guys find this useful.

Ankit Kumar Gupta
  • 3,994
  • 4
  • 31
  • 54
6

From SDWebImage Documentation :

Using blocks

With blocks, you can be notified about the image download progress and whenever the image retrieval has completed with success or not:

// Here we use the new provided sd_setImageWithURL: method to load the web image

for Swift :

cell.imageView.sd_setImageWithURL(url, placeholderImage:nil, completed: { (image, error, cacheType, url) -> Void in
            if (error) {
                // set the placeholder image here

            } else {
                // success ... use the image
            }
        })

for Objective-C

    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
                      placeholderImage:nil
                             completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                                    if (error) {
                                      self.imageView.image = [UIImage imageNamed:@"placeHolderImage"];
                                    }
                                 }];
Mostafa Sultan
  • 2,268
  • 2
  • 20
  • 36
1

You can do that by passing nil to the placeholder attribute and handling the completion block yourself.

Like this :

    [self.imageView sd_setImageWithURL:self.imageURL
                  placeholderImage:nil
                           options:nil
                          progress:nil
                         completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                             if(!error) {
                                 self.imageView.image = image;
                             } else {
                                 self.imageView.image = [UIImage imageNamed:@"placeHolder"];
                             }
                             }];

I haven't tried that. Try it and tell me if that worked for you.

Haroun SMIDA
  • 1,106
  • 3
  • 16
  • 32
1

Here you go, an extension for separating loading/error images. loadingImage will be what SDWebImage called placeholderImage. errorImage will be the real placeholder when loading went wrong.

import Foundation
import SDWebImage

extension UIImageView {
    /// Separated loader and error images, short version.
    func zap_setImage(with url: URL?, loadingImage: UIImage?, errorImage: UIImage) {
        self.zap_setImage(with: url, loadingImage: loadingImage, errorImage: errorImage, completed: nil)
    }

    /// Separated loader and error images, long version.
    func zap_setImage(with url: URL?, loadingImage: UIImage?, errorImage: UIImage, completed: SDExternalCompletionBlock?) {
        self.sd_setImage(with: url, placeholderImage: loadingImage, options: []) { [weak self] (uiimage: UIImage?, error: Error?, sdimagecachetype: SDImageCacheType, usedurl: URL?) in
            //print("ISSUE1688 uiimage: \(String(describing: uiimage)), error: \(String(describing: error))")

            let setErrorImage: Bool
            switch error {
            case .none:
                // No error?
                if uiimage == nil {
                    // No error, but no image, so use error image
                    setErrorImage = true
                }
                else {
                    setErrorImage = false
                }
                break
            case .some(_):
//          case .some(let errorvalue):
                // Error?
                //print("ISSUE1688 errorvalue: \(errorvalue)")
                setErrorImage = true
                break
            }

            //print("ISSUE1688 setErrorImage: \(setErrorImage)")
            if setErrorImage {
                self?.image = errorImage
            }

            if let c = completed {
                c(uiimage, error, sdimagecachetype, usedurl)
            }
        }
    }
}
Jonny
  • 15,955
  • 18
  • 111
  • 232
1

You can use this.

cell.img_UserProfile.sd_setImage(with: URL.init(string: "\(BaseURL_Image)\(image)"), placeholderImage: #imageLiteral(resourceName: "Group 1131"), options: .highPriority, context: [:])
Sukma Saputra
  • 1,539
  • 17
  • 32
0

With 'SDWebImage', '~> 4.0' Use this imageview extension

extension UIImageView {

    func setImage(imageString: String, localUri: String = "", placeHolderImage: UIImage? = nil, loader: Bool = true,  loaderType : UIActivityIndicatorView.Style = .white) {

        self.sd_setShowActivityIndicatorView(loader)
        self.sd_setIndicatorStyle(loaderType)

        if let url = URL(string: localUri), let data = try? Data(contentsOf: url), let img = UIImage(data: data) {

            self.sd_setImage(with: URL(string: imageString), placeholderImage: img, options: SDWebImageOptions(), progress: { (progress, total, url) in

            }) { (img, err, type, url) in

            }


        } else {
            self.sd_setImage(with: URL(string: imageString), placeholderImage: placeHolderImage, options: SDWebImageOptions(), progress: { (progress, total, url) in

            }) { (img, err, type, url) in

            }
        }
    }
}
Rajan Singh
  • 202
  • 2
  • 7