【问题标题】:UILabel in a custom UIButton that adjusted to the button's size with AutoLayout自定义 UIButton 中的 UILabel 使用 AutoLayout 调整到按钮的大小
【发布时间】:2019-12-18 14:45:54
【问题描述】:

我希望将 UILabel 放在自定义 UIButton 中,并限制按钮大小,但要调整前导和尾随约束常量。 这个想法是使 UILabel 比按钮宽度小一点(标签从按钮中获取字体并使用自动缩小)。

使用我的自定义按钮的编码器在 init 中添加相关代码会导致约束不满足错误。

label = UILabel(frame: bounds)
addSubview(label)

translatesAutoresizingMaskIntoConstraints = false

label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10.0).isActive = true
label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
label.topAnchor.constraint(equalTo: topAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

当我删除“10.0”常量时,它可以正常工作,但这个想法是给标签一个不同的大小,而不是按钮的确切大小。 任何想法? 谢谢

【问题讨论】:

    标签: ios swift uibutton autolayout uilabel


    【解决方案1】:

    找到解决方案,必须将 translatesAutoresizingMaskIntoConstraints 也添加到标签中:

    label.translatesAutoresizingMaskIntoConstraints = false
    

    【讨论】:

      【解决方案2】:

      尝试设置button.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0),而不是附加标签和约束,并使用按钮的常规标题。

      代替常规的UIButton,创建它的子类,并覆盖按钮的intrinsicContentSize 方法以保持自动调整大小的可能性:

      class MyButton : UIButton {
         open override var intrinsicContentSize: CGSize {
              get {
                  var ics = super.intrinsicContentSize
                  ics.width = (ics.width < CGFloat(UINT16_MAX)) ? CGFloat(ceil(ics.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right)) : ics.width
                  ics.height = (ics.height < CGFloat(UINT16_MAX)) ? CGFloat(ceil(ics.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom)) : ics.height
                  return ics
              }
         }
      }
      

      如果你需要两个标签(原生按钮的titleLabel + 你的标签),方法是一样的:

      class MyButton : UIButton {
         var labelLeading : NSLayoutConstraint!
         var labelTrailing : NSLayoutConstraint!
         var labelTop : NSLayoutConstraint!
         var labelBottom : NSLayoutConstraint!
         let label = UILabel(frame: bounds)
      
         public override init(frame: CGRect) {
             super.init(frame: frame)
             internalInit()
         }
      
         public required init?(coder: NSCoder) {
             super.init(coder: coder)
             internalInit()
         }
      
         private func internalInit() {
             addSubview(label)
             /// !!! Important to make label to not translate its autoresizing mask, not the button
             label.translatesAutoresizingMaskIntoConstraints = false
      
             labelLeading = label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10.0)
             labelTrailing = label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
             labelTop = label.topAnchor.constraint(equalTo: topAnchor)
             labelBottom  = label.bottomAnchor.constraint(equalTo: bottomAnchor)
             NSLayoutConstraint.activate([labelLeading, labelTrailing, labelTop, labelBottom)
         }
      
         open override var intrinsicContentSize: CGSize {
              get {
                  var ics = super.intrinsicContentSize
                  ics.width = (ics.width < CGFloat(UINT16_MAX)) ? CGFloat(ceil(ics.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right)) : ics.width
                  ics.height = (ics.height < CGFloat(UINT16_MAX)) ? CGFloat(ceil(ics.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom)) : ics.height
                  return ics
              }
         }
      }
      

      【讨论】:

      • 谢谢!然而,这不会完全达到我所需要的。我想我的问题没有足够的上下文,抱歉,将尝试解释:想要创建一个带有标签的按钮,里面有前导和尾随填充。按钮将位于具有固定大小的超级视图中,按钮可以小于或等于其超级视图。按钮的文本来自配置,因此它的长度可以变化。我希望按钮从标签(intrinsicContentSize)中获取其大小,但如果按钮将达到超级视图宽度,则填充将缩小。旨在使用优先级低于 superview 的约束。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 2013-08-19
      • 1970-01-01
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      相关资源
      最近更新 更多