UIImageView 在不同设备上保留情节提要“预览屏幕边界” - 框架不根据屏幕尺寸更新

Posted

技术标签:

【中文标题】UIImageView 在不同设备上保留情节提要“预览屏幕边界” - 框架不根据屏幕尺寸更新【英文标题】:UIImageView retains the Storyboard "preview screen bounds" on different devices - Frame not updating based on screen size 【发布时间】:2018-11-07 04:27:47 【问题描述】:

当我在模拟器中运行我的应用程序时,我的故事板预览选择手机的高度和重量仍然得到。

不应该选择哪种模拟器?

例如: storyboard preview 选择 iPhoneSE 然后选择 image view

体重 = 96

身高 = 92

storyboard preview 选择 iPhone8 然后选择 image view

体重 = 112.5

身高 = 108.5

但是当我在故事板预览时选择 iPhoneSE 和模拟器,无论选择哪一个,比如 iPhone 8、iPhoneX...

体重 = 96

身高 = 92

为什么?

最奇怪的是同一个模拟器,当我选择不同的故事板预览时,我得到不同的大小......

print(self.img.frame.height)
print(self.img.frame.width)

【问题讨论】:

你是否限制了图像视图? 它在桩视图和桩视图等高。 你对父视图的 UIStackView 有限制吗? 我的所有权益视图约束均由等高乘数乘以 super.height。我的其他 ui 单元像按钮标签一样正常。故事板视图只影响图像视图。 我遇到了同样的问题。 Xcode Storyboard 中的“View As”会影响构建时视图的大小。这发生在模拟器和设备上。我正在调查,如果找到解决方案,我会通知您。 【参考方案1】:

我遇到了同样的问题,我认为在上面的描述中不太容易理解。要重新创建它,请执行以下步骤:

设置:

1) 在 Xcode 中启动一个新的“单一视图应用程序”。我目前正在使用 Xcode 10.2.1

2) 进入 Storyboards 并添加一个带有某种背景颜色的 UIView 对象,使其可见

3) 为这个新视图提供一些自动约束,例如前导、尾随、中心 Y 和 1:1 的纵横比。只要确保不给它一个固定的高度或宽度。

4) 在ViewController.swift中,为这个UIView添加一个IBOutlet变量如'myView',并连接起来,方便引用。

5) 在viewDidLoad()中,添加打印语句,效果如下,

print("Bounds of myView: \(myView.bounds)")

测试问题:

现在,回到 Interface Builder,将预览或底部的“查看方式”设置为“iPhone SE”。然后,在您选择模拟器的顶部,也选择“iPhone SE”。现在运行应用程序。

在控制台中,您将看到带有视图边界的打印语句,并且在视觉上一切看起来都很好。

现在,将 Interface Builder 的预览“查看为”选项更改为“iPhone 8”,但在 iPhone SE 上保留模拟器选项 同样,在“iPhone SE”模拟器中运行该应用程序。

就像以前一样,由于自动布局,视觉上一切正常。但是,控制台中打印的边界信息不同。这与“iPhone 8”或在 Interface Builder 中选择用于预览的任何设备相匹配。

举一个更明显的例子,为 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 中使用什么预览选项,模拟器都会在生命周期的这一点上记录正确的边界信息。

因此,对于任何在代码中使用boundsframe 属性来实现本示例中的视图的项目,应将任何代码引用放置在viewDidLayoutSubviews() 方法中。

【讨论】:

这个解决方案什么也没做,你只是重写了一个 superview 方法并在其中创建了一个 print 语句,这实际上是你的视图获得实际边界的地方。 是的。这就是我要对提出问题的人提出的观点。如果他们想要访问视图的实际计算边界,他们需要在viewDidLayoutSubviews() 而不是viewDidLoad() 内进行。 println 语句就在那里,所以他们可以看到证明。【参考方案2】:

如果您添加了 leading, trailing, top and bottom 约束,您将在不同的屏幕尺寸上获得不同尺寸的 imageView,并且如果您希望 imageView 在每个屏幕上具有固定尺寸,那么您可以使用 centerXcenterY 约束定位并添加恒定的宽度和高度

示例 1

示例 2

添加 imageView 的宽度和高度

添加 centerX 和 centerY 约束

解释

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

【讨论】:

我的问题是为什么故事板视图选择不同的预览视图可以影响真正选择模拟器 我在 iPhone 8 模拟器上运行我的应用程序,但故事板视图不是 iPhone 8,然后图像视图的宽度和高度将是故事板视图。我很困惑,如果我建立 ipa 会发生什么?根据情节提要选择建筑时的视图? 故事板预览显示您的应用程序在不同模拟器上的实际外观。通过使用这个特性,我们不需要在多个模拟器上运行我们的应用程序来查看不同设备上的实际外观,我们可以通过简单地在 Interface Builder 中更改预览设备来做到这一点 预览设备会影响真正的运行模拟器。如果我通过 iPhone 6 或 8 预览并在 iPhone 8 上运行会有所不同... 我在 ios 开发中做了一年多,但从未遇到过类似的事情,这对我来说听起来不合逻辑

以上是关于UIImageView 在不同设备上保留情节提要“预览屏幕边界” - 框架不根据屏幕尺寸更新的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式更改使用自动布局在情节提要上创建的 UIImageView 的大小?

启动图像情节提要添加了 Imageview ,但更改资产文件夹中的图像实际上并未反映在设备上?

如何在情节提要中使用自动布局在不同设备尺寸上设置动态位置的约束

如何创建 UILabel 和 UIImageView 以使它们在情节提要文档大纲中为灰色?

快速以编程方式创建后如何在情节提要中链接 UIButton

UIImageView 根据方向使用不同的图像