【发布时间】:2015-10-30 14:55:58
【问题描述】:
当使用自动布局创建 UIButton 时,intrinsicContentSize 总是根据不同的文本字体大小包含不同的顶部/底部填充。我尝试设置contentEdgeInsets,但它不适用于顶部/底部填充。
如何将填充固定为 0 或任何常量值?
【问题讨论】:
标签: ios objective-c uibutton autolayout padding
当使用自动布局创建 UIButton 时,intrinsicContentSize 总是根据不同的文本字体大小包含不同的顶部/底部填充。我尝试设置contentEdgeInsets,但它不适用于顶部/底部填充。
如何将填充固定为 0 或任何常量值?
【问题讨论】:
标签: ios objective-c uibutton autolayout padding
看看这是否有效。为 UIButton 的 titleLabel 而不是按钮本身创建垂直约束。
【讨论】:
为 Swift 5 更新
如果您希望按钮根据其 titleLabel 的内容调整大小,我发现这样做的唯一方法是继承 UIButton 并覆盖intrinsicContentSize。希望这对你有用!
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
}
}
【讨论】:
titleEdgeInsets(或其他插图)似乎不再起作用了
titleEdgeInsets。
经过一些实验,如果您尝试将contentEdgeInsets 设置为全零,则使用默认插入。但是,如果您将它们设置为几乎为零,它会起作用:
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0.01, bottom: 0.01, right: 0)
这些值似乎也得到了floor'd,因此您实际上不会得到小数填充。
【讨论】:
Interface Builder 中转换回0,认为它在.xib/.storyboard 文件中正确设置为0.01。
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)
仅将标题边缘插入清零只会将前导和尾随插入清零。因此,我们还必须将 content-edge insets 归零以将顶部和底部归零。
为了方便:
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 中弃用了 contentEdgeInsets 和 titleEdgeInsets,但在 iOS 15.2 上设置 . contentEdgeInsets 和 .titleEdgeInsets 都没有对我有用。如果您在 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)
])
【讨论】: