如果可以避免,我不想使用子视图。我想要一个带有背景图像,文本和图像的UIButton。现在,当我这样做的时候,图像在文本的左边。背景图像、文本和图像都有不同的高亮状态。


当前回答

做你自己。Xcode10 swift4,

用于编程UI设计

 lazy var buttonFilter : ButtonRightImageLeftTitle = {
    var button = ButtonRightImageLeftTitle()
    button.setTitle("Playfir", for: UIControl.State.normal)
    button.setImage(UIImage(named: "filter"), for: UIControl.State.normal)
    button.backgroundColor = UIColor.red
    button.contentHorizontalAlignment = .left
    button.titleLabel?.font = UIFont.systemFont(ofSize: 16)
    return button
}()

边缘插入值应用于矩形以收缩或展开 用矩形表示的面积。通常,使用边缘嵌入 在视图布局期间修改视图的框架。积极的价值观 将被插入(或缩小)指定数量的帧。负 值使帧由指定的对象开始(或展开) 量。

class ButtonRightImageLeftTitle: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        guard imageView != nil else { return }

        imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: -((imageView?.bounds.width)! + 10), bottom: 0, right: 0 )

    }
}

用于StoryBoard UI设计

其他回答

约束条件呢?与semanticContentAttribute不同,它们不会改变语义。也许是这样的:

 button.rightAnchorconstraint(equalTo: button.rightAnchor).isActive = true

或者在Objective-C中:

[button.imageView.rightAnchor constraintEqualToAnchor:button.rightAnchor].isActive = YES;

警告:未经测试,iOS 9+

把@Piotr的答案变成了一个Swift扩展。请确保在调用此函数之前设置好图像和标题,以便按钮大小适当。

 extension UIButton {
    
    /// Makes the ``imageView`` appear just to the right of the ``titleLabel``.
    func alignImageRight() {
        if let titleLabel = self.titleLabel, imageView = self.imageView {
            // Force the label and image to resize.
            titleLabel.sizeToFit()
            imageView.sizeToFit()
            imageView.contentMode = .ScaleAspectFit
            
            // Set the insets so that the title appears to the left and the image appears to the right. 
            // Make the image appear slightly off the top/bottom edges of the button.
            self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -1 * imageView.frame.size.width,
                bottom: 0, right: imageView.frame.size.width)
            self.imageEdgeInsets = UIEdgeInsets(top: 4, left: titleLabel.frame.size.width,
                bottom: 4, right: -1 * titleLabel.frame.size.width)
          }
        }
     }

子类化UIButton是完全没有必要的。相反,你可以简单地为图像设置一个高的左插入值,为标题设置一个小的右插入值。就像这样:

button.imageEdgeInsets = UIEdgeInsetsMake(0., button.frame.size.width - (image.size.width + 15.), 0., 0.);
button.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., image.size.width);

在Xcode 13.3中,我通过以下几个步骤解决了这个问题,并为图像添加了填充。

创建按钮后,按照下面列出的步骤执行:

首先定义图像: let symbol = UIImage(named: "把你的符号的名字放在这里") 然后在你创建按钮的viewDidLoad中,初始化1中上面定义的图像,将图像添加到按钮并设置属性: 按钮。setImage(符号,用于:.normal) 按钮。semanticContentAttribute = .forceRightToLeft button.configuration ?。imagePadding = 2

不要忘记将按钮添加到视图。

一个快速的选项,做什么你想要不玩任何插图:

class RightImageButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let  textSize = titleLabel?.intrinsicContentSize(),
                imageSize = imageView?.intrinsicContentSize() {
            let wholeWidth = textSize.width + K.textImageGap + imageSize.width
            titleLabel?.frame = CGRect(
                x: round(bounds.width/2 - wholeWidth/2),
                y: 0,
                width: ceil(textSize.width),
                height: bounds.height)
            imageView?.frame = CGRect(
                x: round(bounds.width/2 + wholeWidth/2 - imageSize.width),
                y: RoundRetina(bounds.height/2 - imageSize.height/2),
                width: imageSize.width,
                height: imageSize.height)
        }
    }

    struct K {
        static let textImageGap: CGFloat = 5
    }

}