在 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(forContentRecttitleRect(forContentRectintrinsicContentSize 以获得所需的效果

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)