AutoLayout: UIImageView and Aspect Fit content mode

ぐ巨炮叔叔 提交于 2019-12-10 18:00:53

问题


I'm trying to place an UIImageView in the parent view's center. Image must keep its original aspect ratio and also it shouldn't exceed parent's bounds. So landscape images should be limited by parent's width and portrait images should occupy as much vertical space as needed keeping original ratio.

Sounds like quite a simple task for AutoLayout, right? Here's my setup for UIImageView:

  • center vertically in parent
  • center horizontally in parent
  • imageView.width <= superview.width
  • imageView.height <= superview.height

I also set contentMode to Aspect Fit. Everything works really great for small images which are smaller than device screen but for some reason my UIImageView takes more space than its underlying UIImage for large images (notice the green background - imageView.backgroundColor = [UIColor greenColor]).

Why is this happening? I am not an AutoLayout expert by my constraints look reasonable to me. If I use smaller images like 200x400 then UIImageView takes exactly 200x400 points on the screen with no extra green areas.

I'd like to add borders and rounded corners which obviously won't work properly in this case.


回答1:


This is happenning because you've set width and height constraints as <=. For small images imageView's frame is calculated without any issues and all constraints are satisfied. But when a big image is set, imageView's size is going to be set so that the image fits, but at the same it is limited by the size of the superview (screen size).

  • If you know aspect ratio for sure, you can set it as a constraint and you won't see any green background.
  • Otherwise just leave your constraints as they are and set background color to clear color. This way any unoccupied zones will be transparent and any image you set will take maximum space in at least one dimension.

Edit:

Probably not the best solution, kind of oldschool. You can add strict width and height constraints and calculate them manually using image's aspectRatio:

@IBOutlet weak var heightConstraint: NSLayoutConstraint!
@IBOutlet weak var widthConstraint: NSLayoutConstraint!

func setImage(image: UIImage) {
    imageView.image = image
    let screenSize = UIScreen.main.bounds.size

    let imageAspectRatio = image.size.width / image.size.height
    let screenAspectRatio = screenSize.width / screenSize.height

    if imageAspectRatio > screenAspectRatio {
        widthConstraint.constant = min(image.size.width, screenSize.width)
        heightConstraint.constant = widthConstraint.constant / imageAspectRatio
    }
    else {
        heightConstraint.constant = min(image.size.height, screenSize.height)
        widthConstraint.constant = heightConstraint.constant * imageAspectRatio
    }
    view.layoutIfNeeded()
}



回答2:


Try to check "Clip to Bounds" for imageView in Interface Builder Clip to Bounds Image View

and you must have a well-defined height and width, not "<="



来源:https://stackoverflow.com/questions/40142558/autolayout-uiimageview-and-aspect-fit-content-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!