Skip to content

Instantly share code, notes, and snippets.

@robertmryan
Last active January 20, 2019 00:38
Show Gist options
  • Save robertmryan/687ae5e23672bea2c9331f94992ec5a0 to your computer and use it in GitHub Desktop.
Save robertmryan/687ae5e23672bea2c9331f94992ec5a0 to your computer and use it in GitHub Desktop.
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)
])
}
}
@mickspecial
Copy link

mickspecial commented Jan 20, 2019

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

@robertmryan
Copy link
Author

@mickspecial - OK, I’ll check in later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment