我想在两行文本的左边放置一个图标,这样在图像和文本开始之间有大约2-3像素的空间。控件本身水平居中对齐(通过接口生成器设置)

这个按钮应该是这样的:

|                  |
|[Image] Add To    |
|        Favorites |

我试图配置这与contenttedgeinset, imageEdgeInsets和titleEdgeInsets无效。我知道,负值会使边缘扩大,而正值会使边缘缩小,使边缘更接近中心。

我试着:

[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];

但这并没有正确显示它。我一直在调整这些值,但从-5到-10的左插入值似乎不会以预期的方式移动它。-10将文本一直向左移动,所以我期望-5将它从左侧移动一半,但事实并非如此。

嵌套背后的逻辑是什么?我不熟悉图像放置和相关术语。

我用这个SO问题作为参考,但我的价值观有些不对。 UIButton:如何使用imageEdgeInsets和titleEdgeInsets居中图像和文本?


当前回答

我的垂直定心方法:

extension UIButton {
    
    /// Layout image and title with vertical centering.
    /// - Parameters:
    ///   - size: The button size.
    ///   - imageTopOffset: Top offset for image.
    ///   - spacing: Distance between image and title.
    func verticalAlignmentByCenter(size: CGSize, imageTopOffset: CGFloat, spacing: CGFloat) {
        let contentRect = contentRect(forBounds: CGRect(origin: .zero, size: size))
        let imageRect = imageRect(forContentRect: contentRect)
        let titleRect = titleRect(forContentRect: contentRect)

        let imageTop = imageTopOffset - imageRect.origin.y
        let imageLeft = contentRect.width/2 - imageRect.width/2
        imageEdgeInsets = UIEdgeInsets(top: imageTop, left: imageLeft, bottom: 0, right: 0)

        let titleTop = imageTopOffset + spacing + imageRect.height - titleRect.origin.y
        let titleLeft = titleRect.origin.x - contentRect.width/2 - titleRect.width/2
        titleEdgeInsets = UIEdgeInsets(top: titleTop, left: titleLeft, bottom: 0, right: 0)
    }
    
}

其他回答

swift 4.2版本的解决方案如下:

let spacing: CGFloat = 10 // the amount of spacing to appear between image and title
self.button?.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: spacing)
self.button?.titleEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: 0)

根据iOS 15及以上版本:

var config = UIButton.Configuration.plain() // depends on the button you want 
config.image = UIImage(named: "view_all") // set the image 
config.imagePadding = 5 // add the insets for the image 
button.configuration = config // assign the config to the button 

来源: https://developer.apple.com/documentation/uikit/uibutton/configuration

在swift 5.3和@ravron的启发下回答:

extension UIButton {
    /// Fits the image and text content with a given spacing
    /// - Parameters:
    ///   - spacing: Spacing between the Image and the text
    ///   - contentXInset: The spacing between the view to the left image and the right text to the view
    func setHorizontalMargins(imageTextSpacing: CGFloat, contentXInset: CGFloat = 0) {
        let imageTextSpacing = imageTextSpacing / 2
        
        contentEdgeInsets = UIEdgeInsets(top: 0, left: (imageTextSpacing + contentXInset), bottom: 0, right: (imageTextSpacing + contentXInset))
        imageEdgeInsets = UIEdgeInsets(top: 0, left: -imageTextSpacing, bottom: 0, right: imageTextSpacing)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: imageTextSpacing, bottom: 0, right: -imageTextSpacing)
    }
}

它增加了一个额外的水平边距,从视图到图像,从标签到视图

在接口生成器中。选择UIButton -> Attributes Inspector -> Edge=Title并修改边缘插入

你可以用这个——来避免很多麻烦

myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;   
myButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

这将自动对齐你所有的内容到左边(或任何你想要的地方)

斯威夫特3:

myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left;   
myButton.contentVerticalAlignment = UIControlContentVerticalAlignment.center;