Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UI按钮高度和自动布局_Ios_Swift_Autolayout - Fatal编程技术网

Ios UI按钮高度和自动布局

Ios UI按钮高度和自动布局,ios,swift,autolayout,Ios,Swift,Autolayout,在我的一个ViewController中,我使用的UIView在底部有两个按钮。显然,我想适应屏幕上的两个按钮,因此我使用以下方法: leftButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16).isActive = true rightButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16).isActive =

在我的一个ViewController中,我使用的UIView在底部有两个按钮。显然,我想适应屏幕上的两个按钮,因此我使用以下方法:

leftButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16).isActive = true
rightButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16).isActive = true
//16 points between the buttons
leftButton.rightAnchor.constraint(equalTo: rightButton.leftAnchor, constant: -16).isActive = true 
//right alignment for the buttons
rightButton.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -16).isActive = true 
//left padding for the left button - 16 points
leftButton.leftAnchor.constraint(greaterThanOrEqualTo: self.leftAnchor, constant: 16).isActive = true 

//rightButton can't be less wide than 1/3 of its superview
rightButton.widthAnchor.constraint(greaterThanOrEqualToConstant: widthOfTheView / 3).isActive = true
它可以工作,但是如果我有一个很长的左键标题呢?我的左钮扣变大了,没问题。但我右边的按钮还是不高,看起来有点难看

好的,但是如果我告诉自动布局,我希望右按钮与左按钮具有相同的高度,该怎么办

rightButton.heightAnchor.constraint(equalTo: leftButton.heightAnchor, constant: 0).isActive = true
我以为这是一个解决方案,但我得到的是:

从技术上讲,他们的身高是相等的,但这不是我想要的结果

我想,问题可能出在按钮内的UIEDGEINSET中,但事实并非如此(我删除了这一行,结果是一样的)

我想我不能在两个按钮之间选择最大高度,并将其用作约束的常量,因为在这个阶段,它们各自的帧为零

我尝试使用另一个UIView作为这两个按钮的容器,但结果是一样的

当然,我可以通过关闭自动布局并计算按钮大小和边框来解决这个问题,但我现在不想这样做

那么,我做错了什么呢?

在下面的行中更改

leftButton.rightAnchor.constraint(equalTo: rightButton.leftAnchor, constant: -16).isActive = true

你可以设置

rightButton.heightAnchor.constraint(equalTo: leftButton.heightAnchor).isActive = true

目前,leftButton的右锚正在尝试填充-16常量,由于左按钮正在使用GreaterEqual拉伸,因此将增加按钮之间的距离,但大小将很好

使用
UIStackView
设置,可以非常轻松地完成此操作

.axis = .horizontal
.alignment = .fill
.distribution = .fillEqually
.spacing = 12

尺寸更改时自动调整:

代码如下:

class MultilineRoundedButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    func commonInit() -> Void {
        self.titleLabel?.numberOfLines = 0
        self.titleLabel?.textAlignment = .center
        self.setContentHuggingPriority(UILayoutPriority.defaultLow + 1, for: .vertical)
        self.setContentHuggingPriority(UILayoutPriority.defaultLow + 1, for: .horizontal)
        self.layer.cornerRadius = 8
    }

    override var intrinsicContentSize: CGSize {
        let size = self.titleLabel!.intrinsicContentSize
        return CGSize(width: size.width + contentEdgeInsets.left + contentEdgeInsets.right, height: size.height + contentEdgeInsets.top + contentEdgeInsets.bottom)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        titleLabel?.preferredMaxLayoutWidth = self.titleLabel!.frame.size.width
    }
}

class TwoButtonsView: UIView {

    let theStackView: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .horizontal
        v.alignment = .fill
        v.distribution = .fillEqually
        v.spacing = 16
        return v
    }()

    let leftButton: MultilineRoundedButton = {
        let v = MultilineRoundedButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Really (really!) long first button title", for: .normal)
        v.backgroundColor = UIColor(red: 184.0 / 255.0, green: 233.0 / 255.0, blue: 133.0 / 255.0, alpha: 1.0)
        return v
    }()

    let rightButton: MultilineRoundedButton = {
        let v = MultilineRoundedButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Second title", for: .normal)
        v.backgroundColor = UIColor(red:  74.0 / 255.0, green: 143.0 / 255.0, blue: 226.0 / 255.0, alpha: 1.0)
        return v
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() -> Void {

        leftButton.titleLabel?.font = UIFont.systemFont(ofSize: 24.0, weight: .bold)
        rightButton.titleLabel?.font = leftButton.titleLabel?.font

        addSubview(theStackView)
        theStackView.addArrangedSubview(leftButton)
        theStackView.addArrangedSubview(rightButton)

        NSLayoutConstraint.activate([
            theStackView.topAnchor.constraint(equalTo: topAnchor),
            theStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
            theStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
            theStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
            ])

    }

}

class TwoButtonViewController: UIViewController {

    let buttonsView: TwoButtonsView = {
        let v = TwoButtonsView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(buttonsView)

        NSLayoutConstraint.activate([
            buttonsView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20.0),
            buttonsView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
            buttonsView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20.0),
            ])
    }

}

此答案是@答案的延续,如果您需要一个方便的扩展来根据其中的文本调整UIButton的大小,请使用以下代码:-

extension UIButton {
func wrapContentHeight(constantValue : CGFloat) -> CGFloat {
    self.titleLabel?.text = self.title(for: .normal)

    self.titleLabel?.numberOfLines = 0
    self.titleLabel?.frame.size.width = self.frame.width
    self.titleLabel?.lineBreakMode = .byWordWrapping
    self.superview?.layoutIfNeeded()

    let height = self.titleEdgeInsets.top + self.titleEdgeInsets.bottom + (self.titleLabel?.frame.height ?? 45)
    if height < constantValue {return constantValue}
    return height
}

您是否尝试过将<代码>设置为大于或等于<代码>左侧按钮。高度锚定<代码>?另外,试着降低优先级,这些组合会有所帮助!也许您可以选择viewDidLayoutSubviews上的mac High并创建constraint@Erumaru是的,试过了(不起作用)。我也有优先权,但是,也许还不够,我会再试一次,谢谢。试过了,没用。事实上,这似乎很奇怪:我对左边的按钮及其高度/宽度非常满意,而对右边的按钮我不满意。我明白你为什么不把两个按钮都修好呢?就像你做的那样?我不能那样做,因为标题是动态的,我事先不知道(我固定了按钮的最小宽度,因为如果按钮太小,用户会感到不方便。好的,那么设置左按钮的宽度将解决您的问题,而不是设置右按钮的宽度或设置两者的宽度。
extension UIButton {
func wrapContentHeight(constantValue : CGFloat) -> CGFloat {
    self.titleLabel?.text = self.title(for: .normal)

    self.titleLabel?.numberOfLines = 0
    self.titleLabel?.frame.size.width = self.frame.width
    self.titleLabel?.lineBreakMode = .byWordWrapping
    self.superview?.layoutIfNeeded()

    let height = self.titleEdgeInsets.top + self.titleEdgeInsets.bottom + (self.titleLabel?.frame.height ?? 45)
    if height < constantValue {return constantValue}
    return height
}
btnHeight.constant = selectionBtn.wrapContentHeight(constantValue: 45)