使用对齐(填充)和分布(按比例填充)的嵌套垂直 StackView 呈现滚动视图内容时出现问题

Problem rendering ScrollView content with a nested vertical StackView with Alignment(Fill) and Distribution(Fill Proportionally)

我正在尝试在 ScrollView 中嵌套一个 stackView,以避免为单个视图(3 个标签和一个 ImageView)设置约束。 在没有 StackView 的情况下,在 ScrollView 中为每个视图设置约束后,一切都像单独的视图一样运行良好。

可以在 ScrollView 中使用 Vertical Stack 吗? 为什么 Distribution = 'Fill Proportionally' 没有按预期呈现?

屏幕截图显示了我对 ScrollView 和 StackView 的约束设置以及带有模拟器输出的属性检查器设置。

Screenshot of constraint settings in IB

您的评论:“我希望 ImageView 在启用两个滚动条(垂直和水平)的情况下理想地匹配图像的原始比例。” 没有任何意义。

我猜你从 https://apod.nasa.gov/apod/ap200116.html 中提取了数据(在你的屏幕截图中)......该页面上的图像是 4096 x 4088 像素。如果你想在启用垂直和水平滚动的情况下显示,整个屏幕将只被图像的一小部分覆盖,用户需要滚动、滚动、滚动、滚动才能看到描述。

更有可能的是,您可能想要的是为您的图像视图选择纵横比——16:10是一个常见的、合理的比例——然后设置imageView 到 Aspect Fit。它看起来像这样:

所以,这是您希望在故事板中布局视图控制器的方式:

当您的文本较长时,描述标签将继续垂直扩展,如果文本足够多,您将进行垂直滚动。

您可能还想在视图中嵌入标签,因此您可以添加一些前导和尾随“填充”space以获得更好的外观。

图像视图的另一个选项是给它一个连接到 @IBOutlet 的高度限制。下载图像后,更改该约束的 .constant 以匹配新图像的纵横比。不过,这需要通过代码来完成 - 你不能直接在 Storyboard 中这样做(除非你总是获得完全相同的尺寸/纵横比图像)。


编辑

这是一种动态调整图像视图大小以匹配下载图像纵横比的方法...

使用相同的 Storyboard 约束设置,将 aspect = 16:10 约束上的 Priority 更改为 High (750)

加载视图时,图像视图将自身与 16:10 宽高比相匹配。

假设您正在使用异步图像下载过程,当图像完成下载时:

// set the image
imageView.image = img
    
// get the aspect ratio
let m = img.size.height / img.size.width
    
// add new aspect ratio constraint to the image view
//  because this constraint will have (by default) a Priority of Required (1000),
//  it will "override" the Storyboard 16:10 constraint that has Priority: 750
self.imageView.heightAnchor.constraint(equalTo: self.imageView.widthAnchor, multiplier: m).isActive = true

// animate the size change
UIView.animate(withDuration: 0.3, animations: { [weak self] in
    guard let self = self else { return }
    self.view.layoutIfNeeded()
})

我在这里放了一个工作示例,您可以尝试一下并检查布局和代码:https://github.com/DonMag/UshaSample