UIButton выравнивает изображение по левому краю и центру текста
Вступление:
У меня есть класс, который наследует от UIButton
, В этом классе я хочу обновить свойства, такие как titleEdgeInsets
, imageEdgeInsets
, contentHorizontalAlignment
,
Мой первый подход был использовать layoutSubviews
:
override func layoutSubviews() {
super.layoutSubviews()
// update properties
}
layoutSubviews
создает бесконечный цикл, так что я искал альтернативный метод.
Мой вопрос:
Это обычный способ, чтобы использовать willMove
метод обновления UIButton
свойства?
override func willMove(toWindow newWindow: UIWindow?) {
super.willMove(toWindow: newWindow)
// update properties
}
Если нет, то почему?
Моя цель - выровнять imageView кнопки слева (с отступами) и центрировать текст.
ОБНОВИТЬ:
Мне нужна кнопка frame.size и bounds.width для расчета положения текста и вида изображения
1 ответ
Все свойства, которые вы упомянули выше, могут быть установлены в init
из UIButton
нет необходимости устанавливать их в layoutSubviews
или же willMove(toWindow
, layoutSubviews
будет вызываться несколько раз, поэтому установка этих свойств снова здесь не имеет смысла. willMove(toWindow
будет вызван, когда кнопка добавлена в некоторый вид и кнопка загружена, но вам не нужно ждать до тех пор, чтобы установить эти свойства. Поскольку у вас уже есть подкласс кнопки, поэтому я бы предложил сделать
class SomeButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.contentHorizontalAlignment = .center
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Кстати создание подкласса UIButton
не рекомендуется, поэтому, если вы хотите просто назначить эти свойства своей кнопке, вы можете иметь расширение для UIButton
extension UIButton {
func applyStyle() {
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.contentHorizontalAlignment = .center
}
}
РЕДАКТИРОВАТЬ:
Это то, что вы хотите??
Независимо от того, что текст, текст всегда в центре, а изображение слева с отступом 10 пикселей
РЕДАКТИРОВАТЬ 2:
Поскольку OP подтвердил это, он хочет, чтобы кнопка была оформлена так, как показано на изображениях выше, разместив код для достижения того же
class SomeButton: UIButton {
var titleFont: UIFont! = nil
var textSize: CGFloat = 0
let imageWidth: CGFloat = 20
let buttonHeight: CGFloat = 30
override init(frame: CGRect) {
super.init(frame: frame)
self.titleFont = titleLabel!.font
self.setTitle("here", for: .normal)
self.setTitleColor(UIColor.red, for: .normal)
self.setImage(UIImage(named: "hand"), for: .normal)
self.backgroundColor = UIColor.green
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
if let string = self.title(for: .normal) {
textSize = string.widthOfString(usingFont: self.titleFont)
//30 because imageWidth + 10 padding
return CGRect(origin: CGPoint(x: 30, y: 0), size: CGSize(width: textSize + 30, height: buttonHeight))
}
return CGRect.zero
}
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
return CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: imageWidth, height: buttonHeight))
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override var intrinsicContentSize: CGSize {
//60 because you need eauql padding on both side 30 + 30 = 60
return CGSize(width: textSize + 60, height: buttonHeight)
}
}
extension String {
func widthOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.width
}
}
Надеюсь, поможет