如何添加约束以使视图的尺寸在方向改变时不会改变?

Posted

技术标签:

【中文标题】如何添加约束以使视图的尺寸在方向改变时不会改变?【英文标题】:How do I add constraints so that my view's dimensions do not change when the orientation changes? 【发布时间】:2019-01-06 09:58:22 【问题描述】:

我希望我的视图具有以下属性(数字是任意选择的):

宽度等于高度除以 1.2 停留在屏幕右下方 纵向时高度为屏幕高度的 1/7 方向改变时宽度和高度不会改变

前三个要求可以很容易地翻译成UILayoutConstraints。我用 SnapKit 完成它们只是因为它读起来更清楚。即使您以前从未使用过 SnapKit,您也应该明白我的意思。

let myView = UIView(frame: .zero)
myView.backgroundColor = .green
view.addSubview(myView)
myView.snp.makeConstraints  (make) in
    make.right.equalToSuperview().offset(-8)
    make.bottom.equalToSuperview().offset(-8)
    make.width.equalTo(myView.snp.height).dividedBy(1.2)
    make.height.equalTo(view.snp.height).dividedBy(7) // *

问题是最后一个要点。当我将设备从纵向旋转到横向时,原来旋转前的宽度变成了旋转后的高度。这导致我的视​​野因此变小。

基本上,我想用类似这样的东西替换标有* 的约束:

make.height.equalTo(max(view.snp.height, view.snp.width)).dividedBy(7)

但我不认为 max(a, b) 是 SnapKit 或 UILayoutConstraint API 中的东西。

肯定还有其他表达“等于哪个长度更长”的方式,对吧?

附:我没有用snapkit 标记它,因为我也会接受使用UILayoutConstraint API 的答案。

【问题讨论】:

仅限 iPhone 还是 iPad 和 iPhone?我问的原因是 iPad 在两个方向上都有相同的尺寸等级,所以你必须做一些额外的工作,但你的问题的简短回答是使用尺寸等级 @Paulw11 iPhone iPad。 @Paulw11 你的意思是我应该检测尺寸等级何时更改为viewWillTransition(to:with:),并根据新的尺寸等级调用snp.remakeConstraints 是的,您可以同时设置两个约束,然后在尺寸等级更改时根据需要激活/停用。这样,您可以在旋转旁边为约束激活设置动画 由于 iPad 在两个方向都有相同的尺寸等级,您需要使用 this technique 覆盖尺寸等级 【参考方案1】:

看起来你有两个选择:

    对高度值进行硬编码。 尝试使用nativeBounds:

此矩形基于纵向向上的设备。该值不会随着设备的旋转而改变。

在这种情况下,height 始终用于纵向模式。

myView.snp.makeConstraints  make in
    make.right.bottom.equalToSuperview().offset(-8)
    let screenHeight = UIScreen.main.nativeBounds.height / UIScreen.main.nativeScale
    let height = screenHeight / 7
    make.width.equalTo(height).dividedBy(1.2)
    make.height.equalTo(height)

【讨论】:

如果硬编码高度值,使用自动布局约束有什么意义?如何添加使用nativeBounds.height 作为第二项的约束? 你自己试过这个代码吗?我试过了,myView 的高度大约是屏幕高度的三分之一(而不是七分之一)。 @Sweeper,是的,对不起,我忘了获取真实的设备高度。查看另一个更新。

以上是关于如何添加约束以使视图的尺寸在方向改变时不会改变?的主要内容,如果未能解决你的问题,请参考以下文章

iOS View 在方向改变时不会改变方向

UIView 子视图不会改变方向

如何防止方向改变180度

隐藏视图时,自动布局中的 Swift 约束不会改变

允许滚动视图的高度根据图像大小而改变

当视图从纵向更改为横向时,方向不会改变