UIButton 左对齐图像和居中文本
UIButton align image left and center text
简介:
我有一个 class,它 从 UIButton
继承了 。在此 class 中,我想 更新 属性,例如 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 来计算文本和图像视图的位置
您上面提到的所有属性都可以在UIButton
的init
中设置,完全没有必要在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
}
}
希望对您有所帮助
简介:
我有一个 class,它 从 UIButton
继承了 。在此 class 中,我想 更新 属性,例如 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 来计算文本和图像视图的位置
您上面提到的所有属性都可以在UIButton
的init
中设置,完全没有必要在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
}
}
希望对您有所帮助