更改代码中的大小类(Swift)

时间:2017-08-14 21:45:44

标签: ios swift size-classes programmatically adaptive-layout

我一直在尝试使用纯代码构建自适应布局(不使用故事板)。我使用布局锚来设置约束,并利用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)>

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

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 个答案:

答案 0 :(得分:4)

问题是您正在创建新约束。尝试保留对约束的引用并更改方法以更新它们

func setupCompactRegular() {

    self.bigLabelCenterYAnchor.constant = -150

}

func setupRegularCompact() {

    self.bigLabelCenterYAnchor.constant = 50

}

如果没有自动更新,请立即致电layoutIfNeeded()