【问题标题】:Changing Size Classes in Code (Swift)在代码中更改大小类 (Swift)
【发布时间】:2018-01-22 19:45:19
【问题描述】:

我一直在尝试以纯代码(不使用故事板)构建自适应布局并开始运行。我使用布局锚来设置约束并利用 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,但这并没有帮助。我在网上搜索了几天。至今没有解决办法。所以我的问题是,在旋转设备时,您如何以正确的方式在尺寸等级之间切换?是否有必要覆盖任何其他方法或其他东西?纯代码中的自适应布局有更好的解决方案吗?当涉及到代码中的自适应布局/大小类/布局锚点和约束(不使用情节提要)时,是否有任何最佳实践? 感谢您的帮助!

附:设置约束的方法有:

func setupCompactRegular() {

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

}

func setupRegularCompact() {

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

}

【问题讨论】:

  • 显示设置方法的代码。您实际上是在编辑现有约束还是只是创建一个附加约束?
  • 刚刚用方法更新了帖子。

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


【解决方案1】:

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

func setupCompactRegular() {

    self.bigLabelCenterYAnchor.constant = -150

}

func setupRegularCompact() {

    self.bigLabelCenterYAnchor.constant = 50

}

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

【讨论】:

  • 非常感谢您的帮助,但我是新手,我很难弄清楚如何引用我的约束。您能否在代码中具体说明具体在哪里,如何创建和保存引用以及在哪里调用 layoutIfNeeded()?谢谢一百万!
  • P.S.什么是 bigLabelCenterYAnchor?它是一个全局变量还是某种 CGFloat 类型的属性或什么?如果是这样,它应该在哪里创建以及在使用锚点时如何应用它?或者你的意思是 self.bigLabel.centerYAnchor?如果是这样,那么就没有常量这样的成员。很抱歉这些新手问题,但我对这些东西不知所措。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 2016-06-05
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
相关资源
最近更新 更多