【问题标题】:How to remove the top and bottom padding of UIButton, when create it using auto layout?使用自动布局创建 UIButton 时如何删除它的顶部和底部填充?
【发布时间】:2015-10-30 14:55:58
【问题描述】:

当使用自动布局创建 UIButton 时,intrinsicContentSize 总是根据不同的文本字体大小包含不同的顶部/底部填充。我尝试设置contentEdgeInsets,但它不适用于顶部/底部填充。

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

【问题讨论】:

    标签: ios objective-c uibutton autolayout padding


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      为 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
          }
      }
      

      【讨论】:

      • 这对我来说非常有效。另一个解决方案不起作用,因为自动布局只是采用了固有的 contentSize。
      • 这行得通。但是,在那之后设置titleEdgeInsets(或其他插图)似乎不再起作用了
      • @Jeroen 我更新了我的答案以演示如何使用此解决方案支持titleEdgeInsets
      【解决方案3】:

      经过一些实验,如果您尝试将contentEdgeInsets 设置为全零,则使用默认插入。但是,如果您将它们设置为几乎为零,它会起作用:

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

      这些值似乎也得到了floor'd,因此您实际上不会得到小数填充。

      【讨论】:

      • 为我工作。谢谢!
      • 奇怪的是它在Interface Builder 中转换回0,认为它在.xib/.storyboard 文件中正确设置为0.01
      【解决方案4】:

      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
      

      【讨论】:

        【解决方案5】:

        不确定是不是因为在 iOS 15 中弃用了 contentEdgeInsetstitleEdgeInsets,但在 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)
                ])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-29
          • 2018-04-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多