Когда вы изменяете .titleLabel
из UIButton
, автоматическая разметка не учитывает ваши изменения.
Чтобы получить правильную многострочную кнопку автоматического определения размера, вам необходимо создать подкласс и возвращает действительный .intrinsicContentSize
.
Вот краткий пример:
@IBDesignable
class MultilineButton: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
commonInit()
setNeedsLayout()
}
func commonInit() -> Void {
self.titleLabel?.numberOfLines = 0
self.titleLabel?.textAlignment = .center
self.contentEdgeInsets = UIEdgeInsets(top: 8.0, left: 8.0, bottom: 8.0, right: 8.0)
}
override var intrinsicContentSize: CGSize {
let size = self.titleLabel!.intrinsicContentSize
return CGSize(width: size.width + contentEdgeInsets.left + contentEdgeInsets.right, height: size.height + contentEdgeInsets.top + contentEdgeInsets.bottom)
}
override func layoutSubviews() {
super.layoutSubviews()
titleLabel?.preferredMaxLayoutWidth = self.titleLabel!.frame.size.width
}
}
Класс помечен @IBDesignable
, поэтому вы можете использовать его в Storyboard / Interface Builder и получать точные результаты. .
Вот вид (в раскадровке) 3 экземпляров этой кнопки. Сначала с коротким заголовком, поэтому его не нужно переносить; затем с заголовком, который делает перенос; и третий с заголовком со встроенными символами новой строки:
Обратите внимание, что этот пример явно устанавливает Content Edge Insets
в 8 пунктов на всех 4 сторонах. Если вы хотите изменить это для отдельных кнопок, потребуется небольшое редактирование.