覆盖视图高度限制为零时,应用程序崩溃

时间:2018-09-21 12:31:03

标签: ios swift layout autolayout constraints

在我的应用中,我有三个UIViews,其中一个UILabel和一个UITableView用于显示用户。当没有用户时,我想完全隐藏视图。当前,我正在尝试将heightAnchor视图设置为零,但这会导致此错误:

  

无法同时满足约束条件。

     

“ NSLayoutConstraint:0x604000286cc0 LebensfitFirebase.SurePeople:0x7ff0305d5d30.height == 300(活动)>”,

     

“ NSLayoutConstraint:0x60c000095b30   LebensfitFirebase.SurePeople:0x7ff0305d5d30.height == 0(活动)>“

     

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

     

NSLayoutConstraint:0x604000286cc0 LebensfitFirebase.SurePeople:0x7ff0305d5d30.height == 300(活动)>

要做这项工作,我需要关注什么?顺便说一句,我将translatesAutoresizingMaskIntoConstraints设置为false。 首先,我将三个视图设置如下:

surePeopleTV.anchor(top: descLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
maybePeopleTV.anchor(top: surePeopleTV.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
nopePeopleTV.anchor(top: maybePeopleTV.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

这是一种用于在一行中设置约束的自定义方法。使用此方法不会将高度常数设置为0。

然后在我的程序的后面,当表视图中的用户更新时,我关心高度限制:

func teilnehmerLoaded() {
    if surePeopleTV.finishedLoading == true && maybePeopleTV.finishedLoading == true && nopePeopleTV.finishedLoading == true {
        view.setNeedsUpdateConstraints()
        for controller in tableViewControllers {
            if controller.users.count > 0 {
                let height: CGFloat = 300
                controller.heightAnchor.constraint(equalToConstant: height).isActive = true
                controller.confBounds()
            } else {
                controller.heightAnchor.constraint(equalToConstant: 0).isActive = true 
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

这会在每次调用函数时产生约束,并导致冲突,而不是您想要的

var heightCon:NSLayoutConstraint!

viewDidLoad

heightCon =  controller.heightAnchor.constraint(equalToConstant: <#defaultHeight#>)
heightCon.isActive = true

然后以恒定值播放

func teilnehmerLoaded() {
    if surePeopleTV.finishedLoading == true && maybePeopleTV.finishedLoading == true && nopePeopleTV.finishedLoading == true {
        view.setNeedsUpdateConstraints()
        for controller in tableViewControllers {
            if controller.users.count > 0 {
                heightCon.constant = 300
                view.layoutIfNeeded()
                controller.confBounds()
            } else {
                heightCon.constant = 0
                view.layoutIfNeeded()
            }
        }
    }
}

顺便说一句:如果您有数组大小写,请使用

var heightCons = [NSLayoutConstraint]()

然后追加创建的约束,并通过teilnehmerLoaded

中的for循环从数组访问它们

另一种最佳方法是

func teilnehmerLoaded() {
    if surePeopleTV.finishedLoading == true && maybePeopleTV.finishedLoading == true && nopePeopleTV.finishedLoading == true {
         for controller in tableViewControllers {
            if let heightCon = controller.constraints.first { $0.identifier == "height" }  {

                  heightCon.constant = controller.users.count > 0 ? 300 : 0
            }
            else {

                  let heightCon = controller.heightAnchor.constraint(equalToConstant:  controller.users.count > 0 ? 300 : 0)
                  heightCon.isActive = true
                  heightCon.identifier = "height"
             }

             if controller.users.count > 0 {
                controller.confBounds()
             }

        }

        view.layoutIfNeeded()
    }
}

答案 1 :(得分:1)

感谢Sh_Khan我能够解决它:

var heightCons = [NSLayoutConstraint]()

ViewDidLoad内部:

for controller in tableViewControllers {
        let heightCon = controller.heightAnchor.constraint(equalToConstant: 0)
        heightCon.isActive = true
        heightCons.append(heightCon)
}

函数现在看起来像这样:

func teilnehmerLoaded() {
    if surePeopleTV.finishedLoading == true && maybePeopleTV.finishedLoading == true && nopePeopleTV.finishedLoading == true {
        for (index, controller) in tableViewControllers.enumerated() {
            var height = CGFloat(controller.users.count) * 60.0
            if controller.users.count > 0 {
                height += (25 + 20)
                heightCons[index].constant = height
                controller.confBounds()
            } else {
                heightCons[index].constant = height
            }
            view.layoutIfNeeded()
        }
    }
}