Assigning "aspect fill" option for background image of uibutton Swift

Viewed 3226

We can set the image of the button to be of aspect fill by :

imageView?.contentMode = UIViewContentMode.ScaleAspectFill

but since I am dealing with the background image, I'm not sure how to access contentMode for the background image.

I know that instead of doing so, I can create a custom class where the image can be centered with the button text centered on top, then set the imageview as aspect fill with the above code, but that seems like a lot more work to achieve the same result.

What's the best way to accomplish this?

2 Answers

For whoever stumbles across this:

The UIImageView that contains backgroundImage is not publicly accessible. See https://developer.apple.com/documentation/uikit/uibutton, there is no such property. I do not why Apple protected that.

First solution

However you can filter your UIButton for all the UIImageViews and set their property to .scaleAspectFit:

    override func layoutSubviews() {
        super.layoutSubviews()
        button
            .subviews
            .filter { $0 is UIImageView }
            .forEach { $0.contentMode = .scaleAspectFit }
    }

Second solution

The first solution could possibly conflict with any other UIImageViews you have in your UIButton. So you could also filter only for the exact background image:

    override func layoutSubviews() {
        super.layoutSubviews()

        let backgroundImage = UIImage(named: "backspace-button")
        let backgroundImageView = button
            .subviews
            .filter { $0 is UIImageView }
            .first(where: { ($0 as? UIImageView)?.image == backgroundImage}) as? UIImageView
        backgroundImageView?.contentMode = .scaleAspectFit
    }

I would not recommend to access the backgroundImageView by its array index. There is no guarantee that this order will be like that forever.

Related