|
import UIKit |
|
|
|
class BasicButton: UIControl { |
|
|
|
// Make this private, as external objects shouldn't interact w this directly |
|
|
|
private var buttonImageView: UIImageView = { |
|
let logoView = UIImageView() |
|
logoView.contentMode = .scaleAspectFill |
|
logoView.tintColor = .blue |
|
logoView.translatesAutoresizingMaskIntoConstraints = false |
|
logoView.isUserInteractionEnabled = false |
|
return logoView |
|
}() |
|
|
|
// But expose `UIImage` property so you can programmatically change the image later |
|
|
|
var image: UIImage? { |
|
get { return buttonImageView.image } |
|
set { buttonImageView.image = newValue } |
|
} |
|
|
|
convenience init(image: UIImage) { |
|
self.init() |
|
self.image = image |
|
} |
|
|
|
// The following two init methods should make sure the control is property configured, too |
|
|
|
override init(frame: CGRect = .zero) { |
|
super.init(frame: frame) |
|
setupView() |
|
} |
|
|
|
required init?(coder aDecoder: NSCoder) { |
|
super.init(coder: aDecoder) |
|
setupView() |
|
} |
|
|
|
// Since you are setting the image view to a fixed size, you might as well declare the |
|
// intrinsicContentSize |
|
|
|
override var intrinsicContentSize: CGSize { |
|
return CGSize(width: 80, height: 80) |
|
} |
|
|
|
} |
|
|
|
private extension BasicButton { |
|
|
|
func setupView() { |
|
addSubview(buttonImageView) |
|
setupLayout() |
|
} |
|
|
|
func setupLayout() { |
|
// Personally, I don't think a view should be setting its `translatesAutoresizingMaskIntoConstraints`; |
|
// it is the responsibility of the presenter to dictate how it wants to use this view; |
|
// I know it feels convenient to do this, but, IMHO, it's not a best practice as this violates |
|
// the open/closed principle. |
|
|
|
translatesAutoresizingMaskIntoConstraints = false |
|
|
|
// If we're going to use hardcoded size, let's use the intrincsic contentSize |
|
|
|
let size = intrinsicContentSize |
|
|
|
// Personally I would never force the image view to be some fixed size, but I did so because you did. |
|
// I'd suggest using the standard leading/trailing/top/bottom constraints, so if the class that uses this |
|
// decides a different size is better, this will accommodate that. But that's up to you. |
|
|
|
NSLayoutConstraint.activate([ |
|
buttonImageView.centerXAnchor.constraint(equalTo: centerXAnchor), |
|
buttonImageView.centerYAnchor.constraint(equalTo: centerYAnchor), |
|
buttonImageView.heightAnchor.constraint(equalToConstant: size.height), |
|
buttonImageView.widthAnchor.constraint(equalToConstant: size.width) |
|
]) |
|
} |
|
} |
Thanks for the help. This is a thinned out version of my actual code, which is much more complex. But, seems to be a mess. If you have time to review it I would be stoked. Will post link soon.
Full Custom Button
https://gist.github.com/mickspecial/284374a3f0c5b8752cac1651f5209e00