Search code examples
iosswiftuitableviewuiimageviewautolayout

UIImageView in UITableViewCell low resolution after resizing


I really got frustrated with auto layout and UITableViewCell stuff. I have a UITableView with dynamic heighted cells. Cells can have an image inside them. Image should fit to UIImageView's width.

Images are larger than UIImageView's size. So, after downloading the image, I resize the image and then put it inside the UIImageView. However, resizing the image with respect to UIImageView's width leads to low resolution as UIScreen's scale is greater than 1. So I tried to increase the expected size of the image after the operation (size= (scale * imageViewWidth, scale * imageViewHeight)).

However, this time, cell's height becomes 2 times bigger. What I'm trying to do is basically, while keeping UIImageView's height the same, increasing the resolution.

class ProgressImageView : UIImageView{
    func setImage(imagePath:String?, placeholder:String, showProgress:Bool, showDetail:Bool){
            if imagePath == nil{
                self.image = UIImage(named: placeholder)
            }else{

                if showProgress{
                    self.setShowActivityIndicatorView(true)
                    self.setIndicatorStyle(.Gray)
                }
                let placeholderImage = UIImage(named: placeholder)
                SDWebImageManager.sharedManager().downloadImageWithURL(NSURL(string: imagePath!), options: SDWebImageOptions.RefreshCached, progress: nil, completed: { (image, error, _, _, _) in
                    //resize image to fit width
                    if error != nil{
                        self.image = placeholderImage
                    }else {
                        self.setImageFitWidth(image)
                    }
                })
            }
    }
}

extension UIImageView{
    func setImageFitWidth(image: UIImage){
        let w = self.bounds.size.width //* UIScreen.mainScreen().scale
        print ("ImageView size:\(self.bounds.size) scaled width:\(w)")
        self.image = image.convertToWidth(w)
    }
}

extension UIImage{
    func convertToWidth(let width: CGFloat) -> UIImage{
        print ("Old image size:\(self.size)")
        let ratio = self.size.width / width
        let height = self.size.height / ratio
        let size = CGSizeMake(width, height)
        print ("New image size:\(size)")
        UIGraphicsBeginImageContext(size)
        self.drawInRect(CGRectMake(0, 0, size.width, size.height))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

As you can see in setImageFitWidth method, without UIScreen.mainScreen().scale it works just fine except the resolution and with the scale, UIImageView doubles in size. By the way, I tried all possible options of the content mode (aspect fit, aspect fill etc.) and I am using auto layout.

Result in low resolution:

enter image description here

Result in high resolution:

enter image description here

I want my screen to be just like in the first ss but with resolution of the image in second ss.


Solution

  • Try using UIGraphicsBeginImageContextWithOptions(size: size, opaque: YES, scale: 0) to draw your image. Scale 0 means the function will get the proper scale factor from the device.