【问题标题】:Set Autolayout Constraints Relative to Device Size设置相对于设备大小的自动布局约束
【发布时间】:2015-03-21 05:18:08
【问题描述】:

我陷入了依赖自动布局的陷阱。我目前有一个带有大量 UIView 的 ViewController,并意识到它们在较小的设备(iPhone 4s 和 5)上会失真。

是否可以在 Autolayout 中设置相对于设备大小的约束。

例如,我有一个 UIView 与其他几个 UIViews 对齐的边缘。我想将那个 UIView 的 Autolayout 高度更改为设备高度的一半。

【问题讨论】:

  • “我掉进了依赖 Autolayout 的陷阱”——这不是陷阱,如果你花时间好好学习的话,它是一项非常有用且强大的技术。
  • 我强烈建议学习如何以编程方式处理约束。它非常强大,是迄今为止我最喜欢的布局视图的方式(并不是我在抨击故事板,它们也很棒)。
  • 根据我下面的回答 - 我尽可能使用大小类约束,但有些事情很难实现(但值得简化以找到一个好的方法),所以我开发了一种以编程方式调整一个或两个约束(IBOutletted)的方法,如图所示。有些人发誓严格以编程方式管理自动布局,但可能首先从 Interface Builder 开始并真正熟悉它是一个更好的起点。

标签: objective-c swift autolayout


【解决方案1】:

是的。有一种方法可以通过屏幕尺寸进行限制。

他们被称为size classes

在 Interface Builder 中,查看屏幕底部显示 wAny hAny 的栏,这些是下拉菜单。选择设备的高度和宽度以及要将其约束到的方向的组合,当您在该模式下创建约束时,它们将特定于该尺寸/方向。您还可以在 Interface Builder 的检查器、约束编辑器窗格中添加和修改特定于尺寸的约束。

如果您需要调整一些无法通过 size clases 方便地完成的极端情况,您可以为约束创建一个 IBOutlet 并在代码中引用它,并在视图出现和更改时对其进行修改,类似于下面的例子。这比尝试以编程方式从头开始生成约束要容易和安全得多。

注意:通过 IB 插座修改 NSLayout 约束时,您只能调整 constant 字段,而不是 multiplier,因为 multiplier 在运行时是只读的。所以无论你使用什么比例因子(如果有的话)都必须乘以你用于常量的任何最终值。

@IBOutlet var tableYTopConstraint : NSLayoutConstraint!

override func viewWillAppear(animated: Bool) {
     adjustViewLayout(UIScreen.mainScreen().bounds.size)
}

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        adjustViewLayout(size)
}

func adjustViewLayout(size: CGSize) {
    switch(size.width, size.height) {
    case (320, 480):                        // iPhone 4S in portrait
        tableYTopConstraint.constant = 0
    case (480, 320):                        // iPhone 4S in landscape
        tableYTopConstraint.constant = 0
    case (320, 568):                        // iPhone 5/5S in portrait
        tableYTopConstraint.constant = 0
    case (568, 320):                        // iPhone 5/5S in landscape
        tableYTopConstraint.constant = 0
    case (375, 667):                        // iPhone 6 in portrait
        tableYTopConstraint.constant = 0
    case (667, 375):                        // iPhone 6 in landscape
        tableYTopConstraint.constant = 0
    case (414, 736):                        // iPhone 6 Plus in portrait
        tableYTopConstraint.constant = 0
    case (736, 414):                        // iphone 6 Plus in landscape
        tableYTopConstraint.constant = 0
    default:
        break
    }
    view.setNeedsLayout()

}

【讨论】:

  • 太棒了!感谢你的回答。如果我同时设置了wAny hAnywCompact hCompact 约束,那将是先例?
  • 当您选择 w 和 h 时,它会弹出一个显示蓝色矩形的弹出窗口。在描述您选择的方向的矩形下方的文本中,它描述了 w 和 h 的组合适用于哪些模型和哪些方向。宽度不优先于高度,反之亦然。它们一起指定了特定的尺寸等级
  • 所以我在wCompact hAny 中为视图设置了约束。如果我想以编程方式执行此操作,有什么等价的?
  • 我一直在开发的应用程序使用基于 IB 的自动布局,在这个应用程序中分配 w/Interface Builder 约束创建和编程对我来说是不值得的。在某个时候学习 100% 编程并学习自动布局符号语言(而不是长函数名称/参数列表)以创建约束是一个好主意。不要尝试删除/交互 w/ios 生成的约束。您可以为 ViewController 禁用这些并创建和管理您自己的。除了我上面的回答中所示之外,您可能会非常困惑并创建很多问题来破解您没有创建的约束。
  • Emma 你可以在 iOS9 中尝试新的自动布局语法和指南。 UIStackView 也是一个新的强大的视图。此外,您的第一个 ViewController 中的主 UIView 会自动限制为屏幕大小。 @nerdistcolony 你可以使用fallthroughiPhone 4S in portraitiPhone 6 Plus in portrait 来简化你的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
相关资源
最近更新 更多