UIImageView在不同设备上保留了Storyboard的“预览屏幕边界” - 根据屏幕大小未更新框架

4
当我在模拟器中运行我的应用程序时,高度和宽度仍然是从我的storyboard预览选择的手机中获取的。
不应该选择哪种模拟器?
例如: 在storyboard预览中选择iPhoneSE,然后查看图像视图
重量=96 高度=92
在storyboard预览中选择iPhone8,然后查看图像视图
重量=112.5 高度=108.5
但当我在storyboard预览中选择iPhoneSE并且无论选择哪个模拟器,如iPhone 8、iPhoneX等时,都会得到相同的重量和高度。
为什么?
最奇怪的是,当我选择不同的故事板预览时,相同的模拟器大小也会不同...
print(self.img.frame.height)
print(self.img.frame.width)

你有对图像视图进行约束吗? - Tung Vu Duc
它是一个桩视图,而且桩视图高度相等。 - ZhouLianYou
您的UIStackView是否受父视图的限制? - D V
所有我的占股视图约束都使用等高乘数由super.height设置。我的其他UI单元都很正常,如按钮标签。只有imageView会受到storyboard视图的影响。 - ZhouLianYou
我遇到了同样的问题。在Xcode的Storyboard中,“View As”会影响构建时视图的大小。这在模拟器和设备上都发生了。我正在研究并将在找到解决方案后告诉你。 - Matt Rundle
显示剩余2条评论
2个回答

2
我曾经遇到过完全相同的问题,但我认为上面的描述并不清晰易懂。要重现此问题,请执行以下步骤:

设置:

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()方法中,以确保在生命周期的正确时间记录边界信息。

这个解决方案什么也没做,你只是覆盖了一个父视图方法并在其中打印了一条语句,实际上这是你的视图获取其实际边界的地方。 - Gulfam Khan
2
是的,这就是我向提问者所表达的观点。如果他们想要访问视图的实际计算边界,他们需要在viewDidLayoutSubviews()中进行,而不是在viewDidLoad()中进行。println语句只是为了让他们看到证据。 - Chuck Taylor

1
如果您添加了“前导、尾随、顶部和底部”约束条件,则在不同的屏幕尺寸上,imageView 的大小将会有所不同。如果您想让 imageView 在每个屏幕上都保持固定大小,则可以使用“centerX”和“centerY”约束进行定位,并添加常量宽度和高度。

image with adjustable width and height

示例2
添加imageView的宽度和高度

enter image description here

添加 centerX 和 centerY 约束。

enter image description here

说明

示例1中,图像的宽度和高度是动态的,在示例2中,无论使用哪个设备显示,imageView的高度和宽度都将相同。


2
我的问题是为什么在故事板视图中选择不同的预览视图会影响所选的模拟器。 - ZhouLianYou
我在iPhone 8模拟器上运行我的应用程序,但故事板视图并不是iPhone 8,那么图像视图的宽度和高度将为故事板视图。我很困惑,如果我构建ipa会发生什么?根据故事板在构建时选择视图吗? - ZhouLianYou
故事板预览可以展示你的应用在不同模拟器上的实际外观。通过使用这个功能,我们不需要在多个模拟器上运行应用程序来查看它在不同设备上的实际外观,只需在界面构建器中简单地更改预览设备即可。 - Gulfam Khan
预览设备会影响真实的运行模拟器。如果我在 iPhone 6 或 8 上预览,而在 iPhone 8 上运行,结果会有所不同... - ZhouLianYou
我从事iOS开发已经有一年多了,但从未遇到过这样的问题,这听起来对我来说是不合逻辑的。 - Gulfam Khan
我也这么认为。我会更换Mac并检查一下。感谢大家。 - ZhouLianYou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接