使用自动布局创建 UIButton 时,如何删除 UIButton 的顶部和底部内边距?

问题描述 投票:0回答:7

使用自动布局创建 UIButton 时,

intrinsicContentSize
始终根据不同的文本字体大小包含不同的顶部/底部填充。我尝试设置
contentEdgeInsets
,但它对于顶部/底部填充并不起作用。

如何将填充固定为0或任何常量值?

ios objective-c uibutton autolayout padding
7个回答
51
投票

经过一些实验,似乎如果您尝试将

contentEdgeInsets
设置为全零,则会使用默认插入。但是,如果您将它们设置为几乎为零,它就会起作用:

button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0.01, bottom: 0.01, right: 0)

看起来这些值也变得

floor
'd,所以你实际上不会得到小数填充。


11
投票

更新为 Swift 5

如果您希望按钮的大小适合其 titleLabel 的内容,我发现唯一的方法是子类化 UIButton 并覆盖内在内容大小。希望这对你有用!

class CustomButton: UIButton {
    override var intrinsicContentSize: CGSize {
        return titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize
    }
}

如果您需要使用

titleEdgeInsets
,您可以像这样更新您的UIButton子类:

class CustomButton: UIButton {
    override var titleEdgeInsets: UIEdgeInsets {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        var sizeWithInsets = titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize
        sizeWithInsets.width += titleEdgeInsets.left + titleEdgeInsets.right
        sizeWithInsets.height += titleEdgeInsets.top + titleEdgeInsets.bottom
        return sizeWithInsets
    }
}

9
投票

CGFloat
有一个
leastNormalMagnitude
值,非常适合这个不幸的 UIKit hack。

someButton.titleEdgeInsets = UIEdgeInsets(top: .leastNormalMagnitude, left: .leastNormalMagnitude, bottom: .leastNormalMagnitude, right: .leastNormalMagnitude)
someButton.contentEdgeInsets = UIEdgeInsets(top: .leastNormalMagnitude, left: .leastNormalMagnitude, bottom: .leastNormalMagnitude, right: .leastNormalMagnitude)

仅将标题边缘插图清零只会将前导和尾随插图清零。因此,我们还必须将内容边缘插入归零,以将顶部和底部归零。

为了方便起见:

extension UIEdgeInsets {
    init(repeating value: CGFloat) {
        self.init(top: value, left: value, bottom: value, right: value)
    }

    static let leastNormalMagnitude = UIEdgeInsets(repeating: CGFloat.leastNormalMagnitude)
}

someButton.titleEdgeInsets = .leastNormalMagnitude
someButton.contentEdgeInsets = .leastNormalMagnitude

7
投票

我在 iOS 15 中遇到了按钮标题周围额外填充的问题,所以我用以下代码解决了这个问题:

if #available(iOS 15.0, *) {
    detailsButton.configuration?.contentInsets = .zero

    // you could also keep padding that is more appropriate in your case
    detailsButton.configuration?.contentInsets = .init(top: 0, leading: 10,
                                                       bottom: 0, trailing: 0)
}

您还可以在属性检查器中将 UIButton 的样式设置为

Default
。它会让按钮看起来和以前一样 iOS 15

帮助我正确理解的文章


1
投票

不确定是否是因为 iOS 15 中弃用了

contentEdgeInsets
titleEdgeInsets
,但设置
. contentEdgeInsets
.titleEdgeInsets
在 iOS 15.2 上都没有对我起作用。如果您在 iOS 15+ 上遇到同样的问题,请在下面评论。

最终我最终手动设置

button.titleLabel
约束来删除填充。

// first disable auto generated constraints
button.titleLabel?.translatesAutoresizingMaskIntoConstraints = false

// then pin titleLabel to the button
NSLayoutConstraint.activate([
            button.titleLabel!.leadingAnchor.constraint(equalTo: button.leadingAnchor),
            button.titleLabel!.trailingAnchor.constraint(equalTo: button.trailingAnchor),
            button.titleLabel!.topAnchor.constraint(equalTo: button.topAnchor),
            button.titleLabel!.bottomAnchor.constraint(equalTo: button.bottomAnchor)
        ])

0
投票

适用于 iOS 15+ 的现代方式

let button = UIButton()
button.configuration = {
    var config = UIButton.Configuration.plain()
    config.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
    return config
}()

-1
投票

看看这是否有效。创建对 UIButton 的 titleLabel 而不是按钮本身的垂直约束。

© www.soinside.com 2019 - 2024. All rights reserved.