Interface Builder: automatically set aspect ratio for UIImageView when using “Aspect Fit”?

六月ゝ 毕业季﹏ 提交于 2020-01-06 07:58:45

问题


The share icon (image is white) below is 114x128 pixels.

Fixing the height in Interface Builder to 23 pixels with AutoLayout then using Aspect Fit for the Content Mode does not change the frame rectangle, though.

This causes issues with alignment since if you want the icon 15 pixels from the trailing edge, it's now hard to do so.

One option is to manually set the aspect ratio (i.e., 114/128) as an AutoLayout constraint within IB.

But this is extremely fragile. If you change the image dimensions, you must remember to adjust the aspect ratio.

Is there a way where IB automatically adjusts the frame rectangle as well as the content?

The last option is to do everything within code, but doing everything within IB would be ideal.

Frame rectangle not changing in IB:

Share icon (white icon so not visible here):


回答1:


I believe you'll have to do this programmatically. If you don't want to do it view by view, just define some subclass (which you can specify as the base class in IB) that sets constraints programmatically

class RatioImageView: UIImageView {

    private var ratioConstraint: NSLayoutConstraint?

    override var image: UIImage? {
        didSet { updateRatioConstraint() }
    }

    override func didMoveToSuperview() {
        super.didMoveToSuperview()

        updateRatioConstraint()
    }

    private func updateRatioConstraint() {
        if let ratioConstraint = ratioConstraint {
            removeConstraint(ratioConstraint)
        }

        guard superview != nil else { return }

        let ratio: CGFloat
        if let image = image {
            ratio = image.size.width / image.size.height
        } else {
            ratio = 1
        }

        ratioConstraint = widthAnchor.constraint(equalTo: heightAnchor, multiplier: ratio)
        ratioConstraint?.isActive = true
    }
}

This does it on an image view, but you could presumably do the same with UIButton or whatever, too.


Or in another variation of the theme, you could control this with intrinsic size, where perhaps you explicitly set the height (and because this is @IBInspectable, you can do this right in IB), and it will return the intrinsic size scaled for that height:

@IBDesignable
class RatioImageView: UIImageView {

    @IBInspectable var height: CGFloat = 0

    override var intrinsicContentSize: CGSize {
        guard let image = image else { return .zero }
        guard height > 0 else { return image.size }

        let ratio = image.size.width / image.size.height

        return CGSize(width: height * ratio, height: height)
    }

}


来源:https://stackoverflow.com/questions/47964843/interface-builder-automatically-set-aspect-ratio-for-uiimageview-when-using-as

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