我曾经遇到过完全相同的问题,但我认为上面的描述并不清晰易懂。要重现此问题,请执行以下步骤:
设置:
1)在Xcode中启动新的“单视图应用程序”。我目前使用的是Xcode 10.2.1
2)进入Storyboards并添加一个UIView对象,并设置其背景颜色以使其可见。
3)给这个新视图一些自动约束,例如前导、后续、垂直居中和1:1的纵横比。只需确保不给它固定的高度或宽度。
4)在ViewController.swift
中,添加一个IBOutlet变量,如'myView',用于引用此UIView,并将其连接以便轻松引用。
5)在viewDidLoad()
中,添加类似于以下内容的打印语句:
print("Bounds of myView: \(myView.bounds)")
测试问题:
现在回到Interface Builder,在底部设置预览或“查看为”为“iPhone SE”。然后,在顶部选择模拟器时,也选择“iPhone SE”。现在运行应用程序。
在控制台中,您将看到带有视图边界的打印语句,一切在视觉上看起来都很好。
现在将Interface Builder的预览“查看为”选项更改为类似“iPhone 8”的东西,但保持模拟器选项为iPhone SE。再次在“iPhone SE”模拟器中运行应用程序。
与之前一样,由于自动布局,视觉上一切都很好。但是,控制台中打印的边界信息不同。这与在Interface Builder中选择的“iPhone 8”或其他设备相匹配。
为了获得更明显的示例,请在Interface Builder中选择iPad Pro之类的内容,然后在iPhone SE模拟器上运行它。视觉上一切都正常,但控制台中的bounds
信息完全不正确。它与接口预览相关,而不是与正在测试的设备相关。
当您编写使用处于自动布局约束下的对象边界信息的代码时,就会出现问题,这些约束没有固定的宽度和高度。
解决方案:
在ViewController.swift
中,在viewDidLoad()
方法后添加以下内容。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("Bounds of myView in viewDidLayoutSubviews: \(myView.bounds)")
}
现在,无论我们在Interface Builder中使用哪种预览选项,模拟器都会在生命周期的这一点记录正确的边界信息。
因此,对于任何使用代码中的bounds或frame属性的项目,例如本示例中的视图,应将引用该边界的任何代码放置在viewDidLayoutSubviews()方法中。
最初的回答:请将对bounds的引用放在viewDidLayoutSubviews()方法中,以确保在生命周期的正确时间记录边界信息。