使用自动布局创建 UIButton 时,
intrinsicContentSize
始终根据不同的文本字体大小包含不同的顶部/底部填充。我尝试设置 contentEdgeInsets
,但它对于顶部/底部填充并不起作用。
如何将填充固定为0或任何常量值?
经过一些实验,似乎如果您尝试将
contentEdgeInsets
设置为全零,则会使用默认插入。但是,如果您将它们设置为几乎为零,它就会起作用:
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0.01, bottom: 0.01, right: 0)
看起来这些值也变得
floor
'd,所以你实际上不会得到小数填充。
更新为 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
}
}
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
我在 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
帮助我正确理解的文章。
不确定是否是因为 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)
])
适用于 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
}()
看看这是否有效。创建对 UIButton 的 titleLabel 而不是按钮本身的垂直约束。