在 swift 中在 UIButton 上显示图像和标题
To show image and title on UIButton in swift
在我的 UIButton 中,我想同时显示图像和文本。当我添加以下代码时,只显示图像而不显示文本。谁能帮我解决这个问题?
override func layoutSubviews() {
super.layoutSubviews()
guard imageView != nil else {
return
}
imageView?.frame.size.width = 25
imageView?.frame.size.height = 25
imageEdgeInsets.left = 0
titleEdgeInsets = UIEdgeInsets(top: 10, left: 25, bottom: 5, right: 0)
图中有4个按钮。但是这里只显示图片,没有显示文字。
2-当我尝试以下代码时,输出是
imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 25), bottom: 5, right: 0)
titleEdgeInsets = UIEdgeInsets(top: 10, left: 0, bottom: 5, right: (imageView?.frame.width)!)
但这里我希望图像在左侧,文字在右侧
您可以子类化 UIButton
并覆盖 imageRect(forContentRect
、titleRect(forContentRect
和 intrinsicContentSize
以获得所需的效果
class MyButton: UIButton {
var titleFont: UIFont! = nil
var textSize: CGFloat = 0
override init(frame: CGRect) {
super.init(frame: frame)
self.titleFont = titleLabel?.font ?? .none
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.titleFont = titleLabel?.font ?? .none
}
override var intrinsicContentSize: CGSize {
CGSize(width: textSize + 40, height: 30)
//why height is 30? You want your imageView to be of height 25 and want top and bottom insets to be 5 each so 25 + 5 + 5 = 30
//Why textSize + 40? You want your button to take appropriate size of text + 5 left inset of image + 25 of imageView + 5 left inset of title + 5 right inset of title
}
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
return CGRect(x: 5, y: 2.5, width: 25, height: 25)
//why x is 5 because you want your image to have left inset of 5
//why y is 2.5 ? Your button height is 30, image height is 25 so (30 - 25) / 2 = 2.5
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
if let string = self.title(for: .normal) {
textSize = string.widthOfString(usingFont: titleLabel!.font)
return CGRect(origin: CGPoint(x: 35, y: 0), size: CGSize(width: textSize + 35, height: 30))
//same explanation why x is 35 ? 5 (left inset of image) + 25 (image width) + 5 (left inset of text) = 35
}
return CGRect.zero
}
}
extension String {
func widthOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.width
}
}
如何使用?
像平常一样使用它UIButton
这是我在代码中使用它的方式
let myButton = MyButton()
myButton.backgroundColor = UIColor.red
myButton.setImage(.checkmark, for: .normal)
myButton.setTitle("Checked", for: .normal)
myButton.setTitleColor(.blue, for: .normal)
self.view.addSubview(myButton)
myButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([myButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
myButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50)])
输出:
虽然 x 和 y 坐标似乎是硬编码的,但它们不是,它们是相对值并且适用于任何类型的文本(只要按钮图像的宽度和高度为 25)
在我的 UIButton 中,我想同时显示图像和文本。当我添加以下代码时,只显示图像而不显示文本。谁能帮我解决这个问题?
override func layoutSubviews() {
super.layoutSubviews()
guard imageView != nil else {
return
}
imageView?.frame.size.width = 25
imageView?.frame.size.height = 25
imageEdgeInsets.left = 0
titleEdgeInsets = UIEdgeInsets(top: 10, left: 25, bottom: 5, right: 0)
图中有4个按钮。但是这里只显示图片,没有显示文字。
2-当我尝试以下代码时,输出是
imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 25), bottom: 5, right: 0)
titleEdgeInsets = UIEdgeInsets(top: 10, left: 0, bottom: 5, right: (imageView?.frame.width)!)
但这里我希望图像在左侧,文字在右侧
您可以子类化 UIButton
并覆盖 imageRect(forContentRect
、titleRect(forContentRect
和 intrinsicContentSize
以获得所需的效果
class MyButton: UIButton {
var titleFont: UIFont! = nil
var textSize: CGFloat = 0
override init(frame: CGRect) {
super.init(frame: frame)
self.titleFont = titleLabel?.font ?? .none
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.titleFont = titleLabel?.font ?? .none
}
override var intrinsicContentSize: CGSize {
CGSize(width: textSize + 40, height: 30)
//why height is 30? You want your imageView to be of height 25 and want top and bottom insets to be 5 each so 25 + 5 + 5 = 30
//Why textSize + 40? You want your button to take appropriate size of text + 5 left inset of image + 25 of imageView + 5 left inset of title + 5 right inset of title
}
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
return CGRect(x: 5, y: 2.5, width: 25, height: 25)
//why x is 5 because you want your image to have left inset of 5
//why y is 2.5 ? Your button height is 30, image height is 25 so (30 - 25) / 2 = 2.5
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
if let string = self.title(for: .normal) {
textSize = string.widthOfString(usingFont: titleLabel!.font)
return CGRect(origin: CGPoint(x: 35, y: 0), size: CGSize(width: textSize + 35, height: 30))
//same explanation why x is 35 ? 5 (left inset of image) + 25 (image width) + 5 (left inset of text) = 35
}
return CGRect.zero
}
}
extension String {
func widthOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.width
}
}
如何使用?
像平常一样使用它UIButton
这是我在代码中使用它的方式
let myButton = MyButton()
myButton.backgroundColor = UIColor.red
myButton.setImage(.checkmark, for: .normal)
myButton.setTitle("Checked", for: .normal)
myButton.setTitleColor(.blue, for: .normal)
self.view.addSubview(myButton)
myButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([myButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
myButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50)])
输出:
虽然 x 和 y 坐标似乎是硬编码的,但它们不是,它们是相对值并且适用于任何类型的文本(只要按钮图像的宽度和高度为 25)