Michael Voccola Michael Voccola - 5 months ago 58
Swift Question

UIView Subclass fixed height on initialization

I have a UIButton subclass that needs to be 80pt in height but have width behave normally when used in UIStackView etc... How can this be accomplished in the subclass.

The below code successfully changes the height, but the UIStackView does not adjust the layout to accurate the height:

class MenuSelectionButton: UIButton {

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.cornerRadius = 5.0
}

override func layoutSubviews() {
super.layoutSubviews()
var newFrame = frame
newFrame.size.height = 80
frame = newFrame
}

}


Working Code:

class MenuSelectionButton: UIButton {

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.cornerRadius = 5.0
addHeightConstraint()
}

private func addHeightConstraint () {
let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
NSLayoutConstraint.activateConstraints([heightConstraint])
}

}

Answer

Constrain the button's height to 80 and let auto layout handle it.

Alternatively, since you're using a custom subclass of UIButton, override instrinsicContentSize to return a height of 80:

import UIKit

@IBDesignable
class MenuSelectionButton: UIButton {

    // Xcode uses this to render the button in the storyboard.
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    // The storyboard loader uses this at runtime.
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    override func intrinsicContentSize() -> CGSize {
        return CGSize(width: super.intrinsicContentSize().width, height: 80)
    }

    private func commonInit() {
        self.layer.cornerRadius = 5.0
    }

}
Comments