pruette
pruette

Reputation: 53

ScaleAspectFit blank spaces, imageView.image nul

I have a UIImageView, where the image is set with a given url. Then, I set the content mode to Scale Aspect Fit. This works fine, but there is a ton of blank space before and after the image, when the image is supposed to be directly at the top of the screen.

What I would like to do is rescale the UIImage size (maybe frame?) to match the new size created when Aspect Fit is applied (seems to be the suggestion most people received).

The problem is, whenever I test previous solutions, I'm getting a nul error. Particularly:

import UIKit
import AVFoundation

class OneItemViewController: UIViewController {

    @IBOutlet weak var itemImage: UIImageView!
    @IBOutlet weak var menuButton: UIBarButtonItem!
    @IBOutlet weak var titleText: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let imageURL:NSURL? = NSURL(string: "https://upload.wikimedia.org/wikipedia/commons/d/d5/Pic_de_neige_cordier_Face_E.jpg")

        if imageURL != nil {
            itemImage.sd_setImageWithURL(imageURL)

            itemImage.contentMode = UIViewContentMode.ScaleAspectFit

            AVMakeRectWithAspectRatioInsideRect(itemImage.image!.size, itemImage.bounds)

            /**
             let imageSize:CGSize = onScreenPointSizeOfImageInImageView(itemImage)
             var imageViewRect:CGRect = itemImage.frame
             imageViewRect.size = imageSize
             itemImage.frame = imageViewRect
             **/
        }

        if self.revealViewController() != nil {
            menuButton.target = self.revealViewController()
            menuButton.action = "revealToggle:"
            self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        }

        self.titleText.text = "Title: " + "Earl and Countess of Derby with Edward, their Infant Son, and Chaplain"

        // Do any additional setup after loading the view.
    }


    /**


    func onScreenPointSizeOfImageInImageView(imageV: UIImageView) -> CGSize {

        var scale: CGFloat

        if (imageV.frame.size.width > imageV.frame.size.height) {
            if (imageV.image!.size.width > imageV.image!.size.height) {
                scale = imageV.image!.size.height / imageV.frame.size.height
            } else {
                scale = imageV.image!.size.width / imageV.frame.size.width
            }
        } else {
            if (imageV.image!.size.width > imageV.image!.size.height) {
                scale = imageV.image!.size.width / imageV.frame.size.width
            } else {
                scale = imageV.image!.size.height / imageV.frame.size.height
            }
        }

        return CGSizeMake(imageV.image!.size.width / scale, imageV.image!.size.height / scale)
    }

    **/
}

Tried two things here to get rid of blank space.

First attempt is the call to AVMakeRectWithAspectRatioInsideRect.

Second attempt is the two chunks of code in the /** **/ comments. (onScreenPointSizeOfImageInImageView function and calls to it in viewDidLoad.)

But I can't tell if either work because itemImage.image!.size is causing an error.

So two questions:

1) Why is itemImage.image!.size giving me a nil while unwrapping?

2) Has anyone found a faster solution to removing blank spaces caused by AspectFit?

Upvotes: 1

Views: 1589

Answers (2)

karmingc
karmingc

Reputation: 31

This answer is answered programmatically with UIKit with Swift 5

As mentioned by @Ignelio, using NSLayoutConstraint would do the work for UIImageView.

The reasoning is that you want to keep maintain the aspect ratio - by using

// let UIImage be whatever you decide to name it
UIImage.contentMode = .scaleAspectFit

would make the UIImage inside the UIImageView fit back to its ratio size given the width. However, as mentioned in Apple's documentation, that will leave remaining area with transparent spacing. Hence, what you want to tackle is UIImageView's size/frame.

-- With this method, you're giving your UIImageView its width constraint equal to the UIImage's ratio - scaling back perfectly in regards to its parent's width constraint (whatever that may be).

// let UIImageView be whatever you name
UIImageView.widthAnchor.constraint(equalTo: UIImageView.heightAnchor, multiplier: UIImage.size.width / UIImage.size.height).isActive = true

Upvotes: 3

Ignelio
Ignelio

Reputation: 121

imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor, multiplier: image.size.width / image.size.height).isActive = true

Upvotes: 3

Related Questions