2017-08-14 79 views
1

我一直试图站起来,用纯代码构建自适应布局(不使用故事板)上运行。我用布局锚设置的限制和利用traitCollectionDidChange方法各组约束和其他接口的变化之间变化。我使用switch语句用相应的一组约束来调用相应的方法。大小的改变类

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 
    super.traitCollectionDidChange(previousTraitCollection) 

    switch (traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) { 
    case (.regular, .regular): 
     setupRegularRegular() 

    case (.compact, .compact): 
     setupCompactCompact() 

    case (.regular, .compact): 
     setupRegularCompact() 

    case (.compact, .regular): 
     setupCompactRegular() 

    default: break 
    } 

} 

为了测试,我只改变了一个约束,它是centerYAnchor.constraint。在人像定为-150,在景观我希望它被改为50为iPad,我设置了固定为0

bigLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -150).isActive = true 

iPhone和iPad之间切换时,它工作正常。但是,如果你开始从纵向到横向旋转iPhone,布局系统出现故障时,曰:

[LayoutConstraints] Unable to simultaneously satisfy constraints. 
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(
"<NSLayoutConstraint:0x600000097890 UILabel:0x7fac02c08aa0'Main Label'.centerY == UIView:0x7fac02e0a950.centerY - 150 (active)>", 
"<NSLayoutConstraint:0x604000097840 UILabel:0x7fac02c08aa0'Main Label'.centerY == UIView:0x7fac02e0a950.centerY + 50 (active)>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x604000097840 UILabel:0x7fac02c08aa0'Main Label'.centerY == UIView:0x7fac02e0a950.centerY + 50 (active)> 

我试图重写各种方法和设置约束为false,然后的isActive属性回到真实的,但没有帮助。我在网上搜索了几天。目前还没有解决方案。所以我的问题是,如何在旋转设备时正确切换尺寸类别?是否有必要重写其他方法或其他?纯代码中的自适应布局是否有更好的解决方案?在代码中使用自适应布局/尺寸类别/布局锚点和约束时(不使用故事板),是否有最佳实践? 感谢您的帮助!

P.S.该方法建立约束:

func setupCompactRegular() { 

    bigLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -150).isActive = true 

} 

func setupRegularCompact() { 

    bigLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 50).isActive = true 

} 
+1

显示您的设置方法的代码。你实际上是在编辑现有的约束还是只创建一个额外的约束? – dan

+0

刚用方法更新了帖子。 – Andrei

回答

2

的问题是要创建新的约束..抱着试试看你的约束参考,如果之后改变你的方法来更新他们

func setupCompactRegular() { 

    self.bigLabelCenterYAnchor.constant = -150 

} 

func setupRegularCompact() { 

    self.bigLabelCenterYAnchor.constant = 50 

} 

呼叫layoutIfNeeded()它不自动更新

+0

非常感谢您的帮助,但我是新来的这个东西,我有一个很难搞清楚如何保存引用我的约束。请您在代码究竟去哪里,如何建立和保持参考和确切位置调用layoutIfNeeded()指定?太感谢了! – Andrei

+0

P.S.什么是bigLabelCenterYAnchor?它是一个全局变量还是某种类型的CGFloat类型的属性或什么?如果是这样,应该在什么地方创建以及如何在使用锚时应用它?或者,也许你的意思是self.bigLabel.centerYAnchor?如果是这样,那么就没有这样的成员不变。对于那些新手问题抱歉,但我被这个东西淹没了。 – Andrei