【发布时间】:2026-01-11 08:50:01
【问题描述】:
启动 Xcode 并为清楚起见仅构建 9.3 通用应用程序。因此,将 9.3 iPad 与 9.3 iPhone 进行比较。为模拟器和设备构建 - 在两者上发布展览。
应用程序在所有四个方向上旋转。
有一个典型的情况,你会做这样的事情......
@IBOutlet weak var doorHeightPerScreen: NSLayoutConstraint!
var heightFraction:CGFloat = 0.6
{
didSet
{
if ( heightFraction > maxHeight ) { heightFraction = maxHeight }
if ( heightFraction < minHeight ) { heightFraction = minHeight }
let h = view.bounds.size.height
spaceshipHeightPerScreen.constant = h * heightFraction
self.view.layoutIfNeeded() // holy! read on....
}
}
注意更改约束后的layoutIfNeeded()。
继续典型的例子,你会得到类似的东西
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
heightFraction = (heightFraction)
// use "autolayout power" for perfection every pass.
// now that basic height/position is set,
save/load reactive positions...
position detail stuff...
}
检查一下...我整天都在这样做,只是碰巧使用 iPhone。
有趣的是,您不需要 layoutIfNeeded 调用。
@IBOutlet weak var doorHeightPerScreen: NSLayoutConstraint!
var heightFraction:CGFloat = 0.6
{
didSet
{
if ( heightFraction > maxHeight ) { heightFraction = maxHeight }
if ( heightFraction < minHeight ) { heightFraction = minHeight }
let h = view.bounds.size.height
spaceshipHeightPerScreen.constant = h * heightFraction
}
}
工作正常。
但是在一天结束时,我把它放在一些 iPad 上,然后....一切都坏了!
每当您旋转横向/纵向时,都会出现问题。
头疼之后,我意识到您确实需要 layoutIfNeeded 调用,在 iPad 上。那是在相同的操作系统上。
确实,无论操作系统版本如何,该行为都会表现出来。它适用于所有 iPhone/所有 iPad。卧槽!
@IBOutlet weak var doorHeightPerScreen: NSLayoutConstraint!
var heightFraction:CGFloat = 0.6
{
didSet
{
if ( heightFraction > maxHeight ) { heightFraction = maxHeight }
if ( heightFraction < minHeight ) { heightFraction = minHeight }
let h = view.bounds.size.height
spaceshipHeightPerScreen.constant = h * heightFraction
self.view.layoutIfNeeded() //MUST HAVE, IN IPAD CASE!!!!!!
}
}
对我来说,非常令人不安他们会以不同的方式工作。
我想知道的是,是否有某个地方可以使它们工作相同?莫非是我的错?
两者之间是否还有其他已知差异 - 或者确实“已知”存在一些这样的错误?
我想不出我在任何地方做过什么奇怪或不寻常的事情,除了整个应用程序在第一个视图中具有override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return .All },如果您想将设备倒置,这是正常的;我怀疑它的相关性。除此之外,它是一个非常“干净”的新鲜应用。
它给了我一种矩阵故障的感觉——太可怕了。
这是什么原因造成的?
根据 RobM 的问题,初始 ViewController 上的 SimulatedMetrics 设置(属性选项卡)是...
应用的通用方案:第一个场景“通用”为全屏,设备大小。 “Live”有一个大小相同的容器(使用“Trailing”等/约束为零)。在 Live 中,有一个容器视图“Quad”,它的大小也完全符合“Live”,所以它也是全屏的。 Quad:UIViewController 展示了我描述的问题。 Quad 包含位于视图周围的各种对象(图像、自定义控件等)。当应用启动时,一切正常。
关于设备(或类似设备)的旋转:在更改约束之后(我不知道这是否相关):iPad 需要layoutIfNeeded 调用 IS(所有 iPad ),但对于 iPhone(所有 iPhone)NOT 是必需的。模拟器和设备上的行为是相同的。
另一个例子.....
我发现了另一个令人震惊的例子。
在 UICollectionView 中,自定义单元格(只是简单的静态大小的单元格)。如果您碰巧更改了约束条件(想象一下,在单元格内调整图标或产品照片的大小)。
在 IPAD 上您做必须确保在 layoutIfNeeded 中重新调整,否则 不会在单元格的第一次出现时工作。
而在 IPHONE 上它的行为肯定是不同的:它会在单元格第一次出现之前“为你做这件事”,如果你碰巧省略了它。
完全怪异!!
我在每台 iPad 和每台 iPhone 上都进行了测试。 (此外,异常行为恰好在设备或模拟器上表现出来:模拟器没有区别。)
【问题讨论】:
-
您在使用情节提要吗?故事板中的视图大小是多少?
-
我的意思是你的场景在故事板中的大小是多少?
-
单击故事板中的初始视图控制器。打开属性检查器。模拟指标下的“大小”是什么?
标签: ios ipad autolayout nslayoutconstraint