Swift:以编程方式更改HeightAnchor

时间:2016-11-16 02:21:29

标签: swift nslayoutconstraint

我正在关注此视频教程:https://www.youtube.com/watch?v=4rNtIeC_dsQ

当我在UI细分控制中选择其他选项时,我正在努力让容器视图的高度发生变化

约17:51左右视频

我声明var就是这样:

var inputsContainerHeightAnchor: NSLayoutConstraint?

对于约束,我现在有:

inputContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
inputContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -60).isActive = true
inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor?.isActive = true

对于我有的段控件:

func handleLoginRegisterChange() {

    let title = segmentedLoginRegisterControl.titleForSegment(at: segmentedLoginRegisterControl.selectedSegmentIndex)

    loginRegisterButton.setTitle(title, for: .normal)

    inputsContainerHeightAnchor?.constant = segmentedLoginRegisterControl.selectedSegmentIndex == 0 ? 100 : 150



}

段控件设置如下:

lazy var segmentedLoginRegisterControl: UISegmentedControl = {
    let sc = UISegmentedControl(items: ["Login", "Register"])
    sc.tintColor = .white
    sc.selectedSegmentIndex = 1
    sc.translatesAutoresizingMaskIntoConstraints = false
    sc.addTarget(self, action: #selector(handleLoginRegisterChange), for: .valueChanged)
    return sc
}()

我正在使用Xcode版本8.1

然而,当我运行它是模拟器时,输入控制器视图是100.当我单击任何段时它不会改变。

有人可以看到我错过的任何内容吗?

3 个答案:

答案 0 :(得分:5)

你未能正确完成的部分发生在视频的16:50开始。但我们可以从您发布的代码中找出问题所在。这些线条很可疑:

inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor?.isActive = true

这些行中的第一行创建了NSLayoutConstraint的实例,但没有激活它并且不会将其存储在变量中。因此约束立即被破坏。除了浪费时间和电池电量之外,它没有任何效果。

这些行中的第二行提到了变量inputsContainerHeightAnchor,它看起来很像应该引用前一行中创建的约束。但前一行并没有为该变量分配任何内容。如果没有其他任何内容为该变量赋值,则该变量为nil。由于使用?代替!取消引用,因此如果变量包含nil,则第二个语句不会执行任何操作。

你可能想写这个:

inputsContainerHeightAnchor = inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor?.isActive = true

第一行将新约束存储在变量中,第二行激活新约束。这是在16:50左右开始的视频中发生的事情。您可能错过的是大约17:15,他说“我们将摆脱let”,同时他从实例变量声明中复制变量名称并将其粘贴到文本let constraint上。线条包裹在他的屏幕上,他的缩进是不正确的,他用键盘快捷键进行复制和粘贴,因此很难遵循。您可能认为他刚刚删除了文本let constraint =。 (这就是为什么当我制作视频时,我会尽量避免键盘快捷键。)

然而,写下这两行更好:

inputsContainerHeightAnchor = inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor!.isActive = true

如果您确定变量为nil,并且nil是编程错误,则使用!取消引用它。如果变量包含nil,程序将在该行上停止(在调试器中,如果在Xcode下运行)。如果您(以及视频的作者)以这种方式编写它,您可能会更快地找到错误,因为在您修复错误之前,程序永远不会超过第二行。

答案 1 :(得分:0)

您是如何将inputsContainerHeightAnchor分配给containerView高度约束的?你实际上可以做到这一点

 @IBOutlet weak var inputsContainerHeightAnchor: NSLayoutConstraint!

并从故事板中为其分配containerView高度。

答案 2 :(得分:0)

要调试的行是:

inputsContainerHeightAnchor?.constant = segmentedLoginRegisterControl.selectedSegmentIndex == 0 ? 100 : 150

现在,首先要确保生产线正在按照您的预期行事。我觉得是这样的。但是......它实际上是在改变inputsContainerHeightAnchor吗?

  • 如何声明此变量?通过IBAction还是通过代码?如果是前者,它是否正确"接线"?是否适当确定范围?

  • 假设你做的一切正确,下一个问题是生命周期序列。你是在改变它而不是让事情变得清爽吗?你能打电话给superview.layoutIfNeeded()吗?

我知道这听起来像是基本的东西,但有时它会让你感到沮丧。

至少,将这个长视频去掉一个功能项目,看看出了什么问题。两个按钮(不是分段控件),只需在点击时更改简单颜色的UIView的高度(使用代码中的AutoLayout)。然后将您发现的内容纳入更大的项目中。