When the screen is rotated from portrait to landscape, more buttons appears then each button become smaller to fit the screen and does its image.
Without any additional codes, the image does not get smaller if its size is smaller than the button's in both portrait and landscape modes. This does not look good. What i want is, for example, the space between the image's top and the button's top should always equal 30% of the button's height and the image should get smaller or bigger according to the space.
I created a custom UIButton as following:
import Foundation
import UIKit
public class CustomButton : UIButton {
private let offset = CGFloat(2.0) // 2 point
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .scaleAspectFit
}
public override func layoutSubviews() {
super.layoutSubviews()
let edge = bounds.height / 3 - offset
self.imageEdgeInsets = UIEdgeInsets(top: edge, left: 0, bottom: edge, right: 0)
}
}
The following line means the button's image scales to fit the available space by maintaining the aspect ratio. In other words, if the image's height changes, its width changes too proportional to the height.
self.imageView?.contentMode = .scaleAspectFit
The imageEdgeInsets property is used to set the spaces around the image on the button. A button can have both image and title (text) at the same time. The titleEdgeInsets property is used to define the spaces around the title. There is another related property called contentEdgeInsets, which is used to set the spaces around both image and title together. I only specified the values of the top and the bottom because I need the top and bottom spaces to be equal.
The layoutSubviews() method is called when bounds or frame property changes, according to https://forums.developer.apple.com/message/317152?et=watches.email.thread#317152.
Unreliable Solution
import Foundation
import UIKit
public class CustomButton : UIButton {
private let offset = CGFloat(2.0) // 2 point
public override var bounds: CGRect {
didSet {
self.boundDidChange()
}
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .scaleAspectFit
}
public func boundDidChange() {
let edge = bounds.height / 3 - offset
self.imageEdgeInsets = UIEdgeInsets(top: edge, left: 0, bottom: edge, right: 0)
}
}
References
https://developer.apple.com/documentation/uikit/uiview/contentmode/scaleaspectfit
https://developer.apple.com/documentation/uikit/uibutton/1624034-imageedgeinsets