简体   繁体   中英

UIButton's backgroundImage's content mode not respected

I'm putting the finishing touches on an app I'm about to publish and I've enountered difficulty getting the contentMode of a UIButton 's background image to be respected. Regardless of the contentMode I specify, the image just gets plopped in the background with no regard for the contentMode setting.

I've looked at a post covering this topic, but it doesn't appear to do anything in my circumstance.

This is called in from viewDidLoad :

// I tried putting the contentMode lines here...
myButton.imageView!.contentMode = .scaleAspectFit
myButton.contentMode = .scaleAspectFit
myButton.setBackgroundImage(UIImage(named: "myImage.png"), for: .normal)

// ...and here
// myButton.imageView!.contentMode = .scaleAspectFit
// myButton.contentMode = .scaleAspectFit

// I threw this in for S's & G's to see if it would work...it didn't
myButton.translatesAutoresizingMaskIntoConstraints = false
myButton.imageView?.translatesAutoresizingMaskIntoConstraints = true

I'm not sure what I'm missing, but I rest assured it will be something startling stupid on my part. I welcome suggestions on how I can get the contentMode of a UIButton 's background image to be respected. Thank you for reading.

Update

The button is typed as a custom button, not a system button.

The problem is that you add an image using setBackgroundImage() method. This adds your image to some private UIImageView that you can't reach directly like myButton.imageView! . In your code, you're applying contentType for you button instead of its background image.

If you want to reach this background UIImageView you need to use subviews array. But if you try to do this inside your viewDidLoad() method, you'll find that background UIImageView hasn't been added yet because your buttons layout method wasn't called. There are 2 ways to fix that.

Solution 1 – call layoutIfNeeded explicitly:

override func viewDidLoad() {
    super.viewDidLoad()

    myButton.setBackgroundImage(UIImage(named: "myImage"), for: .normal)
    myButton.layoutIfNeeded()
    myButton.subviews.first?.contentMode = .scaleAspectFit
}

Solution 2 – move contentMode setup at viewDidAppear method.

override func viewDidLoad() {
    super.viewDidLoad()

    myButton.setBackgroundImage(UIImage(named: "myImage"), for: .normal)
    myButton.setTitle("Some title", for: .normal)
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    myButton.subviews.first?.contentMode = .scaleAspectFit
}

Hope it helps you.

To simplify the accepted answer, all you need to do is layout the subviews and your setup code can be done in one place.

override func viewDidLoad() {
    super.viewDidLoad()

    myButton.setBackgroundImage(UIImage(named: "myImage.png"), for: .normal)
    myButton.layoutIfNeeded()
    myButton.subviews.first?.contentMode = .scaleAspectFill
}

A button's imageView property and backgroundImage property are two separate things.

Unlike the accepted answer, you can use the imageView property instead.

override func viewDidLoad() {
   super.viewDidLoad()

   myButton.setImage(UIImage(named: "myImage.png"), for: .normal)
   myButton.imageView?.contentMode = .scaleAspectFill
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM