iOS Autolayout Visual Format - 如何设置间距以尝试使用一个值但在小屏幕上退回到另一个值?
iOS Autolayout Visual Format - How to set spacing to attempt one value but fall back to another for small screens?
我正在创建一个自定义模态视图,其中包含一堆 UILabel、UIImage 等,并将显示为模态视图。该视图必须使用自动布局,并且必须以编程方式完成,而不是使用 storyboard/xibs(不幸的是)。
模态视图随着内容增长,直到它距离屏幕边缘(顶部、底部、左侧、右侧)8 点。
很多子视图之间的边距是 16 和 24 点。这在较新的 iPhone 和纵向模式下都很棒,并且在屏幕和模态视图之间留下大量 space。
但是当旋转到横向时,模态视图从 top/bottom 边缘达到 8 pt 的限制并且许多子视图完全缩小。
解决方法是将子视图之间的所有 "margins" 更改为 8 点。这让一切都有足够的空间来展示。
我的目标是能够动态调整边距,以便它们 "attempt" 较高的值(即 16、24),但 "fall back" 较小的值(即 8),如果视图已填满屏幕。
我知道一种方法是使用多个约束,并在方向改变时切换它们,但如果可能的话我不想走那条路,因为随着时间的推移在改变时管理起来会很痛苦
前一段时间我确实发现了一个小道消息,它说你可以使用优先级值来做这样的事情:
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(24@200,8@900)-[titleLabel]-[detailsLabel]-(24@200,8@900)-[button(40)]-(24@200,8@900)-|", options: [.AlignAllCenterX], metrics: metrics, views: views))
但是,即使视图的高度有足够的增长空间,它也总是回落到“8@900”值。
我也试过这个,它似乎对一些子视图有效,但不是所有的:
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=8,<=24)-[titleLabel]-[detailsLabel]-(>=8,<=24)-[button(40)]-(>=8,<=24)-|", options: [.AlignAllCenterX], metrics: metrics, views: views))
它不会回退到 8,8 是比 24 更高的优先级约束,因此如果可能,它会这样做。在 Auto Layout 中,1000 被认为是必需的(即,如果有两个互斥的 1000 优先级约束,您将在日志中看到一堆错误)。相反,优先级 0 - 999 都被认为是可选的。任何可选的东西都可以被系统破坏以满足所需的约束,你基本上选择一个介于 0 和 999 之间的值来指定你希望它们被破坏的顺序(0 是第一个被破坏的,999 最后被破坏) .还值得注意的是 various priorities.
发生了各种系统事件
我会考虑通过使较小的边距成为所需优先级 (1000) 的不等式以及较大的边距成为优先级 999 的等式来解决您的问题。这样它将尝试使用 24 点值,但如果它不能在保持其他所需约束的同时这样做,它将使其最小化为 8 个点。
值得注意的是,这两个差距可能不会以相同的速度缩小。为了实现这一点,您可能需要做一些棘手的事情,比如使用直接固定到超级视图的隐藏视图(隐藏视图仍然影响布局)和要求高度 >=8 的标签,以及 24@999 的高度.然后你可以让这两个隐藏视图也被约束为彼此相等。如果您能够支持 iOS 9.x+,则可以使用 UILayoutGuide
。
NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=8,24@999)-[titleLabel]-[detailsLabel]-(>=8,24@999)-[button(40)]-(>=8, 24@999)-|", options: [.AlignAllCenterX], metrics: metrics, views: views)
我想我会在大小 class 更改时调整约束。当大小 class 改变时,只需将常量从 16 调整为 8,而不是有多个约束。
if (self.view.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact)
// set constraints which implement margins to constant of 8
else
// set constraints which implement margins to constant of 16
更多信息here。
我正在创建一个自定义模态视图,其中包含一堆 UILabel、UIImage 等,并将显示为模态视图。该视图必须使用自动布局,并且必须以编程方式完成,而不是使用 storyboard/xibs(不幸的是)。
模态视图随着内容增长,直到它距离屏幕边缘(顶部、底部、左侧、右侧)8 点。
很多子视图之间的边距是 16 和 24 点。这在较新的 iPhone 和纵向模式下都很棒,并且在屏幕和模态视图之间留下大量 space。 但是当旋转到横向时,模态视图从 top/bottom 边缘达到 8 pt 的限制并且许多子视图完全缩小。
解决方法是将子视图之间的所有 "margins" 更改为 8 点。这让一切都有足够的空间来展示。
我的目标是能够动态调整边距,以便它们 "attempt" 较高的值(即 16、24),但 "fall back" 较小的值(即 8),如果视图已填满屏幕。
我知道一种方法是使用多个约束,并在方向改变时切换它们,但如果可能的话我不想走那条路,因为随着时间的推移在改变时管理起来会很痛苦
前一段时间我确实发现了一个小道消息,它说你可以使用优先级值来做这样的事情:
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(24@200,8@900)-[titleLabel]-[detailsLabel]-(24@200,8@900)-[button(40)]-(24@200,8@900)-|", options: [.AlignAllCenterX], metrics: metrics, views: views))
但是,即使视图的高度有足够的增长空间,它也总是回落到“8@900”值。
我也试过这个,它似乎对一些子视图有效,但不是所有的:
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=8,<=24)-[titleLabel]-[detailsLabel]-(>=8,<=24)-[button(40)]-(>=8,<=24)-|", options: [.AlignAllCenterX], metrics: metrics, views: views))
它不会回退到 8,8 是比 24 更高的优先级约束,因此如果可能,它会这样做。在 Auto Layout 中,1000 被认为是必需的(即,如果有两个互斥的 1000 优先级约束,您将在日志中看到一堆错误)。相反,优先级 0 - 999 都被认为是可选的。任何可选的东西都可以被系统破坏以满足所需的约束,你基本上选择一个介于 0 和 999 之间的值来指定你希望它们被破坏的顺序(0 是第一个被破坏的,999 最后被破坏) .还值得注意的是 various priorities.
发生了各种系统事件我会考虑通过使较小的边距成为所需优先级 (1000) 的不等式以及较大的边距成为优先级 999 的等式来解决您的问题。这样它将尝试使用 24 点值,但如果它不能在保持其他所需约束的同时这样做,它将使其最小化为 8 个点。
值得注意的是,这两个差距可能不会以相同的速度缩小。为了实现这一点,您可能需要做一些棘手的事情,比如使用直接固定到超级视图的隐藏视图(隐藏视图仍然影响布局)和要求高度 >=8 的标签,以及 24@999 的高度.然后你可以让这两个隐藏视图也被约束为彼此相等。如果您能够支持 iOS 9.x+,则可以使用 UILayoutGuide
。
NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=8,24@999)-[titleLabel]-[detailsLabel]-(>=8,24@999)-[button(40)]-(>=8, 24@999)-|", options: [.AlignAllCenterX], metrics: metrics, views: views)
我想我会在大小 class 更改时调整约束。当大小 class 改变时,只需将常量从 16 调整为 8,而不是有多个约束。
if (self.view.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact)
// set constraints which implement margins to constant of 8
else
// set constraints which implement margins to constant of 16
更多信息here。