Swift3 我应该激活和停用Swift的哪些生命周期约束

Swift3 我应该激活和停用Swift的哪些生命周期约束,swift3,constraints,lifecycle,xcode8,Swift3,Constraints,Lifecycle,Xcode8,我一直在苦苦思索什么时候是激活或取消激活故事板中约束的正确时间 我已经做了一个极其简化的视图控制器来显示我遇到的这个问题 基本上,有UIView(红色框),里面是UIScrollView,最后里面是包含文本的标签。UIScrollView距离它所在的红色UIView的所有边缘15。UILabel在其内部的UIScrollView的所有侧面上都为0。默认情况下,我有一个从红色UIView底部(称为bottomConst)到超级视图底部的约束。意思是它总是保持相同的距离。如果没有任何改变,它将在4

我一直在苦苦思索什么时候是激活或取消激活故事板中约束的正确时间

我已经做了一个极其简化的视图控制器来显示我遇到的这个问题

基本上,有UIView(红色框),里面是UIScrollView,最后里面是包含文本的标签。UIScrollView距离它所在的红色UIView的所有边缘15。UILabel在其内部的UIScrollView的所有侧面上都为0。默认情况下,我有一个从红色UIView底部(称为bottomConst)到超级视图底部的约束。意思是它总是保持相同的距离。如果没有任何改变,它将在4英寸和4.7英寸屏幕上显示如下方式。这将作为
isActive=true
启动

如您所见,4.7英寸屏幕上有大量空白

为了解决这个问题,我添加了第二个约束来控制红色UIView的高度(称为heightConst),该约束以
isActive=false
的形式启动

我使用该代码在
layoutifneedd()
之后检查UIScrollView的边界高度是否高于UIScrollView的contentSize高度。如果是,则会禁用bottomConst并激活heightConst。问题是,这并没有发生。我最终得到了一个零高度的UIScrollView和一个30高的UIView,因为顶部和底部边缘有15个约束

但如果我在运行它们之前手动进入并切换它们,一切看起来都是正确的

这是我正在使用的代码。(见下文) 我尝试将代码放置在不同的位置,如viewDidLoad、ViewDidDisplay、viewWillLayoutSubviews、viewDidLayoutSubviews。但它们似乎都不起作用。我开始怀疑我是否应该在一个单独的生命周期中调用LayoutIfNeeded(),但是有太多的可能,我想我应该是那些似乎总是最了解情况的人。任何帮助都将不胜感激

import UIKit

class ViewController: UIViewController {

@IBOutlet var bottomConst: NSLayoutConstraint!
@IBOutlet var heightConst: NSLayoutConstraint!
@IBOutlet var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()


}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    scrollView.setNeedsLayout()
    scrollView.layoutIfNeeded()

    let scrollHeight = scrollView.contentSize.height

    if (scrollHeight <= scrollView.bounds.height) {
        bottomConst.isActive = false

        heightConst.constant = scrollHeight + 30
        heightConst.isActive = true

        view.layoutIfNeeded()
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}
导入UIKit
类ViewController:UIViewController{
@IBOutlet var bottomConst:NSLayoutConstraint!
@IBOutlet var heightConst:NSLayoutConstraint!
@iBCROLLVIEW:UIScrollView!
重写func viewDidLoad(){
super.viewDidLoad()
}
重写func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
scrollView.setNeedsLayout()
scrollView.layoutIfNeeded()文件
设scrollHeight=scrollView.contentSize.height

如果(scrollHeight好的话,我能够找到问题的答案。但是它有点复杂,也可能取决于视图控制器的设置方式

对于我上面展示的例子,下面的代码是有效的

import UIKit

class ViewController: UIViewController {

@IBOutlet var bottomConst: NSLayoutConstraint!
@IBOutlet var heightConst: NSLayoutConstraint!
@IBOutlet var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()


}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    view.setNeedsLayout()
    view.layoutIfNeeded()

    let scrollHeight = scrollView.contentSize.height

    if (scrollHeight <= scrollView.bounds.height) {
        bottomConst.isActive = false

        heightConst.constant = scrollHeight + 30
        heightConst.isActive = true
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

但最终,我找到解决办法的方法是放一个
print()
在每个生命周期中运行,并查看它报告的约束是什么。这样,我可以看到它何时出错。希望这对将来的其他人有所帮助!

您做错了。将层次结构设置为scrollview-view-label。将视图设置为与标签相同的大小。完成后,无需更新约束d、 我在想你在这里的建议。我想我应该指出我做view>scrollview>label的原因。我正在使用视图作为颜色背景,并且正在拐弯。否则我只需要scrollview>label。但即使我做了你的建议,我想我仍然会有同样的问题。我必须限制crollview的大小意味着我可以再次使用空白,或者使用比我的viewController更高的scrollview。但是谢谢你的建议。
import UIKit

class ViewController: UIViewController {

var changeSize: Bool = false //Additional Code

@IBOutlet var bottomConst: NSLayoutConstraint!
@IBOutlet var heightConst: NSLayoutConstraint!
@IBOutlet var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()


}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    view.setNeedsLayout()
    view.layoutIfNeeded()

    let scrollHeight = scrollView.contentSize.height

    if (scrollHeight <= scrollView.bounds.height) {
        changeSize = true //Addition Code
        bottomConst.isActive = false

        heightConst.constant = scrollHeight + 30
        heightConst.isActive = true
    }
}

//Addition Code
override function viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if (changeSize == true && heightConst.isActive == false) {
        heightConst.isActive = true
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}