自定义UIButton中的UILabel,已使用AutoLayout将其调整为按钮的大小

时间:2019-08-11 22:39:26

标签: ios swift uibutton autolayout uilabel

我想将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”常量时,它可以正常工作,但是该想法是给标签赋予不同的大小,而不是按钮的确切大小。 任何想法? 谢谢

2 个答案:

答案 0 :(得分:0)

尝试设置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
        }
   }
}

答案 1 :(得分:0)

找到解决方案后,还必须在标签上添加translatesAutoresizingMaskIntoConstraints:

label.translatesAutoresizingMaskIntoConstraints = false