2016-11-16 103 views
2

我下面这个视频教程:https://www.youtube.com/watch?v=4rNtIeC_dsQ斯威夫特:更改HeightAnchor编程

我挣扎着爬容器视线的高度改变时,我选择在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 Version 8.1

但是w当我运行这个是模拟器时,输入控制器视图是100,当我点击任何一个段时它不会改变。

有人可以看到我错过的任何东西吗?

+0

有没有办法让我们不必看17分钟的视频来弄清楚你的问题是什么? –

+1

当时点击视频播放时间线并跳到未来 – JamesG

+0

好的,所以我没有自己编码,但是我刚刚在那个时间前后观看了视频。它看起来像你说的那样完成了。你可能会错过更早的事情吗?这可能不是一个问题。联系作者布莱恩,看看他是否可以帮助? – MarkP

回答

3

你没有做好的部分发生在视频的16:50开始。但是我们可以从您发布的代码中找出问题。这些线是腥:

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

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

其中的第二行提到变量inputsContainerHeightAnchor,看起来很像它应该引用先前行中创建的约束。但是前面的行并没有给这个变量分配任何东西。如果没有其他值为该变量赋值,则该变量为零。由于它是使用?而不是!取消引用的,所以如果变量包含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,该程序将停止(在调试器中,如果在Xcode下运行)。如果你(和视频的作者)以这种方式编写它,你可能很快就会发现错误,因为在修正错误之前,程序永远不会经过第二行。

+0

完美。一个你完全正确的假设,我听到他说删除让位,但没有看到粘贴。这发生在他的另一个视频中,他使用了一个我不知道的快捷方式,并停留了一段时间。非常感谢你做的这些。非常感激。 – JamesG

0

您是如何将inputsContainerHeightAnchor分配给containerView高度约束的?你实际上可以制作它

@IBOutlet weak var inputsContainerHeightAnchor: NSLayoutConstraint! 

然后从storyboard分配containerView的高度。

+0

正是我在我现在删除的答案建议。所以,@JamesG,现在两个人已经独立提出了这个问题。你有什么机会现在就考虑它? – matt

+0

让伊娃变弱是一个坏主意,除非你先将约束存储在一个强大的变量中。语句'inputsContainerHeightAnchor = inputContainerView.heightAnchor.constraint(equalToConstant:150);如果伊娃很弱,inputsContainerHeightAnchor?.isActive = true'将不起作用,因为第二条语句没有强制引用约束,因此它已被销毁。 –

+0

哦,耶。我的错。默认应该很强。谢谢@rob –

0

线调试是:

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

现在,第一件事情就是要确保该行做你期望它是什么。我觉得是这样的。但是......它实际上是否改变了inputsContainerHeightAnchor?

  • 这个变量是如何声明的?通过IBAction或通过代码?如果前者,它是否正确“连线”?它的范围是否合适?

  • 假设你做得正确,下一个问题是生命周期序列。你是否在改变它,但不会让人耳目一新?你可以调用superview.layoutIfNeeded()吗?

我知道这听起来像基本的东西,但是有时候它是你绊倒的小东西。

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