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


当前回答

要在UIButton内右对齐图像,请尝试下面的代码

btn.contentHorizontalAlignment = .right

其他回答

Xcode 11.4 Swift 5.2

对于任何试图镜像后退按钮样式的人,像这样的雪佛龙:

import UIKit

class NextBarButton: UIBarButtonItem {

    convenience init(target: Any, selector: Selector) {

        // Create UIButton
        let button = UIButton(frame: .zero)

        // Set Title
        button.setTitle("Next", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17)

        // Configure Symbol
        let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
        let image = UIImage(systemName: "chevron.right", withConfiguration: config)
        button.setImage(image, for: .normal)

        // Add Target
        button.addTarget(target, action: selector, for: .touchUpInside)

        // Put the Image on the right hand side of the button
        // Credit to liau-jian-jie for this part
        button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

        // Customise spacing to match system Back button
        button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)

        self.init(customView: button)
    }
}

实现:

override func viewDidLoad() {
    super.viewDidLoad()
    let nextButton = NextBarButton(target: self, selector: #selector(nextTapped))
    navigationItem.rightBarButtonItem = nextButton
}

@objc func nextTapped() {
    // your code
}

感谢Vitaliy Gozhenko

我只是想添加,你可以添加IB_DESIGNABLE之前,你的按钮@interface和设置你的按钮类在storyborad。然后你就可以在界面构建阶段实时观看它的布局,而无需启动应用程序

我决定不使用标准的按钮图像视图,因为所提出的移动它的解决方案感觉很俗气。这让我获得了想要的美感,并且通过改变约束来重新定位按钮是很直观的:

extension UIButton {
    func addRightIcon(image: UIImage) {
        let imageView = UIImageView(image: image)
        imageView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(imageView)

        let length = CGFloat(15)
        titleEdgeInsets.right += length

        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: self.titleLabel!.trailingAnchor, constant: 10),
            imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
            imageView.widthAnchor.constraint(equalToConstant: length),
            imageView.heightAnchor.constraint(equalToConstant: length)
        ])
    }
}

对于这个问题,你可以在“label with UIImage view”中创建UIView,并将UIView类设置为UIControl,并创建IBAction为tuch up inside

这里是解决方案的UIButton与中心对齐的内容。 这段代码使图像右对齐,并允许使用imageEdgeInsets和titleEdgeInsets进行宝贵的定位。

用你的自定义类子类化UIButton并添加:

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    CGRect frame = [super imageRectForContentRect:contentRect];
    CGFloat imageWidth = frame.size.width;
    CGRect titleRect = CGRectZero;
    titleRect.size = [[self titleForState:self.state] sizeWithAttributes:@{NSFontAttributeName: self.titleLabel.font}];
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect {
    CGFloat imageWidth = [self imageForState:self.state].size.width;
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    return frame;
}