启用 UIButton 的间距或 contentEdgeInsets 时,UIStackViews 自动布局抛出

Posted

技术标签:

【中文标题】启用 UIButton 的间距或 contentEdgeInsets 时,UIStackViews 自动布局抛出【英文标题】:UIStackViews Autolayout throws when either spacing or contentEdgeInsets of UIButton is enabled 【发布时间】:2018-09-30 12:32:31 【问题描述】:

我有一个UIStackView ParticipateButtonStackView 管理同一类的三个按钮:ParticipateButton

这些按钮只包含一个图像。为了在顶部和底部有一些填充,我设置了UIEdgeInsets。但是这个和.spacing = 1 属性似乎不能同时工作。为什么?


堆栈视图:

class ParticipateButtonStackView: UIStackView 
    //MARK: - Properties & Variables
    var delegate: participateButtonStackViewDelegate?

    //MARK: - GUI Objects
    var buttons: [ParticipateButton]!
    let sureButton = ParticipateButton(type: .sure)
    let maybeButton = ParticipateButton(type: .maybe)
    let nopeButton = ParticipateButton(type: .nope)

    //MARK: - Init & View Loading
    override init(frame: CGRect) 
        super.init(frame: frame)
        self.addBackground(color: UIColor.gray)
        buttons = [sureButton, maybeButton, nopeButton]
        setupStackView()
        setupButtons()
    

    //MARK: - Setup
    func setupStackView() 
        self.axis           = .horizontal
        self.spacing        = 1
        self.alignment      = .leading
        self.distribution   = .fillEqually
    

    func setupButtons() 
        for button in buttons 
            addArrangedSubview(button)
            button.addTarget(self, action: #selector (self.buttonClick(sender:)), for: .touchUpInside)
        
    

参与按钮

class ParticipateButton: UIButton 

    var typeOfButton: participateLists!

    override init(frame: CGRect) 
        super.init(frame: frame)
        self.backgroundColor  = LebensfitSettings.Colors.buttonBG
        self.tintColor        = LebensfitSettings.Colors.basicTintColor
        self.imageView?.contentMode = .scaleAspectFit
        self.contentEdgeInsets = UIEdgeInsets(top: 7, left: 0, bottom: 7, right: 0)
    

    convenience init(type: participateLists) 
        self.init()
        self.typeOfButton = type
        setImage(type: type)
    

    func setImage(type: participateLists) 
        var buttonImage: UIImage?
        switch type 
        case .sure:
            buttonImage = UIImage(named: "pb_sure")?.withRenderingMode(.alwaysTemplate)
        [...]
        
        self.setImage(buttonImage, for: .normal)
    

这是抛出的错误:

将尝试通过打破约束来恢复

NSLayoutConstraint:0x600001adb020 'UISV-spacing' H: [LebensfitFirebase.ParticipateButton:0x7f9899c5eaa0]-(1)-[LebensfitFirebase.ParticipateButton:0x7f9899c5fad0](活动)>

编辑:

participateButtonStackView.leftAnchor = view.leftAnchor
participateButtonStackView.rightAnchor = view.rightAnchor
participateButtonStackView.bottomAnchor = view.bottomAnchor
participateButtonStackView.heightAnchor = equalToConstant(50)

【问题讨论】:

还有哪些其他约束,比如对于 UIStackView? 上面有一个视图层次结构。现在添加。 如果你把高度限制变大有什么变化吗? 不,一切都一样。 我现在看到了。我认为您最好的选择是查看错误消息上方显示的约束列表。尝试找出哪些冲突。我无法想象任何其他问题。这只是花时间隔离冲突的问题。 【参考方案1】:

我无法解决这个问题,所以我构建了这个解决方法:

参与按钮

func setBordersLeftRight() 
    let borderLeft = UIView()
    let borderRight = UIView()
    borderLeft.backgroundColor = .gray
    borderRight.backgroundColor = .gray

    addSubview(borderLeft)
    addSubview(borderRight)
    borderLeft.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0.5, height: 0)
    borderRight.anchor(top: topAnchor, left: nil, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0.5, height: 0)

【讨论】:

以上是关于启用 UIButton 的间距或 contentEdgeInsets 时,UIStackViews 自动布局抛出的主要内容,如果未能解决你的问题,请参考以下文章

UIButton:在文本下方以 x pts 间距画一条线?

调整 titleEdgeInsets 和 imageEdgeInsets 时 UIButton 上的 title 和 text 之间的间距不正确

如何允许自动调整UIButton的大小以满足间距约束

启用/禁用 UIButton 取决于 UITextField 中的文本长度

IOS 13:UITextField rightView的间距问题

修改两个右 UIBarButtonItems 之间的间距