【问题标题】:App crashes when overriding the views height-constraint to zero将视图高度约束覆盖为零时应用程序崩溃
【发布时间】:2019-02-25 20:52:31
【问题描述】:

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

无法同时满足约束。

"NSLayoutConstraint:0x604000286cc0 LebensfitFirebase.SurePeople:0x7ff0305d5d30.height == 300 (active)>",

"NSLayoutConstraint:0x60c000095b30 LebensfitFirebase.SurePeople:0x7ff0305d5d30.height == 0 (active)>"

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

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。

然后在我的程序中,当 tableviews 中的用户更新时,我会关心高度约束:

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 
            }
        }
    }
}

【问题讨论】:

    标签: ios swift layout autolayout constraints


    【解决方案1】:

    这会在每次调用函数时创建约束,并导致您想要的冲突

    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()
        }
    }
    

    【讨论】:

      【解决方案2】:

      感谢 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()
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-13
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多