如何根据用户输入更新约束

时间:2019-03-29 16:08:42

标签: ios swift xcode constraints

我有一个默认情况下具有3个列部分(称为支腿,aViewbViewcView)的视图控制器视图。用户可以在设置菜单中的2到3之间切换,该菜单会在同一屏幕上以模态显示。

我正在尝试让各列在屏幕上平均占用空间,因此,当有3列时,它们各自占据大约1/3的宽度(忽略填充),而当有2列时,它们每个占大约1/2。

我当前的方法是使用if语句设置一些始终处于活动状态的约束,然后根据列数更改那些约束。我尝试了layoutIfNeeded()removeConstraints的一些变体以及其他变体,但不确定如何实现它们。

为澄清代码,xView是列视图,其中包含xTitlexTextView。在文本视图上方还有一个mainButton,在文本视图下方还有一个button1。这一切都存在于contentViewscrollView设置中。


let sidePadding: CGFloat = 15


func placeViews() { // run in viewWillAppear

        let alwaysConstraints = [
            aView.topAnchor.constraint(equalTo: mainButton.bottomAnchor, constant: 25),
            aView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: sidePadding),
            aView.rightAnchor.constraint(equalTo: bView.leftAnchor),
            bView.topAnchor.constraint(equalTo: aView.topAnchor),
            bView.bottomAnchor.constraint(equalTo: aView.bottomAnchor),
            aTitle.topAnchor.constraint(equalTo: aView.topAnchor),
            bTitle.topAnchor.constraint(equalTo: aTitle.topAnchor),
            aTitle.centerXAnchor.constraint(equalTo: aView.centerXAnchor),
            bTitle.centerXAnchor.constraint(equalTo: bView.centerXAnchor),
            aTextView.topAnchor.constraint(equalTo: aTitle.bottomAnchor, constant: 25),
            bTextView.topAnchor.constraint(equalTo: aTextView.topAnchor),
            aTextView.bottomAnchor.constraint(equalTo: aView.bottomAnchor),
            bTextView.bottomAnchor.constraint(equalTo: aTextView.bottomAnchor),
            aTextView.centerXAnchor.constraint(equalTo: aView.centerXAnchor),
            bTextView.centerXAnchor.constraint(equalTo: bView.centerXAnchor),
            aTextView.widthAnchor.constraint(equalTo: aView.widthAnchor),
            bTextView.widthAnchor.constraint(equalTo: bView.widthAnchor),
            bView.widthAnchor.constraint(equalTo: aView.widthAnchor),

            // Restrict buttons to leg views
            button1.heightAnchor.constraint(equalToConstant: buttonHeight),
            button1.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20),
            button1.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20),
            button1.topAnchor.constraint(equalTo: aView.bottomAnchor, constant: 40),

            // Restrict button to bottom
            button1.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20)
        ]




        let twoLegConstraints = [
            aView.widthAnchor.constraint(equalToConstant: (view.frame.width - (sidePadding * 2) / 2)),
            bView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -sidePadding),
        ]

        let threeLegConstraints = [
            aView.widthAnchor.constraint(equalToConstant: (view.frame.width - (sidePadding * 2)) / 3),
            bView.rightAnchor.constraint(equalTo: cView.leftAnchor),
            cView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -sidePadding),
            cView.topAnchor.constraint(equalTo: aView.topAnchor),
            cView.bottomAnchor.constraint(equalTo: aView.bottomAnchor),
            cTitle.topAnchor.constraint(equalTo: aTitle.topAnchor),
            cTitle.centerXAnchor.constraint(equalTo: cView.centerXAnchor),
            cTextView.topAnchor.constraint(equalTo: aTextView.topAnchor),
            cTextView.bottomAnchor.constraint(equalTo: aTextView.bottomAnchor),
            cTextView.centerXAnchor.constraint(equalTo: cView.centerXAnchor),
            cTextView.widthAnchor.constraint(equalTo: cView.widthAnchor),
            cView.widthAnchor.constraint(equalTo: aView.widthAnchor),
        ]





        NSLayoutConstraint.activate(alwaysConstraints)

        if legs == 2 {
            cView.isHidden = true
            NSLayoutConstraint.activate(twoLegConstraints)
        } else if legs == 3 {
            cView.isHidden = false
            NSLayoutConstraint.activate(threeLegConstraints)
        }
    }

此刻,默认情况下,屏幕以3开始,并且可以正常工作(每个屏幕约1/3的宽度)。然后,用户可以将其切换为2,然后再次完美工作(每个屏幕宽度约为1/2)。然后切换回3,前两个完全不更改,第三列显示在屏幕的右边缘。

1 个答案:

答案 0 :(得分:1)

使用带有distribution = .fillEqually的堆栈视图。当您设置任何视图的isHidden属性时,它将自动处理布局和约束。