【问题标题】:Problem rendering ScrollView content with a nested vertical StackView with Alignment(Fill) and Distribution(Fill Proportionally)使用带有对齐(填充)和分布(按比例填充)的嵌套垂直 StackView 渲染 ScrollView 内容的问题
【发布时间】:2021-05-18 05:00:54
【问题描述】:

我试图在 ScrollView 中嵌套一个 stackView 以避免为单个视图(3 个标签和一个 ImageView)设置约束。 如果没有 StackView,事情就像在 ScrollView 中为每个视图设置约束的单个视图一样工作。

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

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

Screenshot of constraint settings in IB

【问题讨论】:

  • 是的,您可以将 StackView 放在 UIScrollView 中。如果您可以分享您的用户界面,您正在尝试做什么。
  • 这是为了学习目的。我正在尝试获取 NASA APOD 信息。我必须显示图片的日期,应该滚动和缩放的图像,需要滚动的描述和最后的版权信息。我是否应该将 ScrollView 与嵌套的 contentView 一起使用,该嵌套的 contentView 具有嵌套的垂直堆栈视图,其中包含所有视图来呈现数据,如上所述。
  • 好的,但我建议使用 UITableView 以获得更好的控制。
  • @UshaDesai - 首先,忘记Fill Proportionally,这不是你想要的。您需要澄清您的意思:“单个视图内容大小超过了固有内容大小。” 显示您当前获得的内容以及您想要的内容 得到。
  • @UshaDesai - 您希望如何调整 imageView 的大小?你想要正方形(1:1 的比例)吗?您希望它与图像的原始比例相匹配吗? (我假设您正在动态填写标签和 imageView...)

标签: ios xcode autolayout


【解决方案1】:

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

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

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

所以,下面是您希望在 Storyboard 中布局视图控制器的方式:

当你有更长的文字时,描述标签会继续垂直扩展,并且有足够的文字你会得到垂直滚动。

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

您的图像视图的另一个选项是给它一个连接到@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

【讨论】:

  • 我现在已经为 imageView 提供了固定的宽度和高度,并使用下载的 UIImage 绘制到 UIGraphicsImageRenderer 上下文中以呈现该图像的缩小版本。有用!我不确定如何使用纵横比以及如何确定高度“.constant”。我为这种情况找到了一个 [stackoverflow.com/questions/26833627/…,但还没有理解案例 3 中给出的代码。
  • @UshaDesai - 您可以动态更改 imageView 的高度以匹配图像的纵横比。请参阅我的答案的编辑
  • 感谢你们(整理我的 StackView 上的自动布局,然后整理 imageView 的动态高度)。一个问题:当所有下载的图像明显大于图像视图时,它们是否都会调整大小。除了我上面使用的那个之外,调整大图像大小的最佳技术是什么。
  • @UshaDesai - imageView 为您调整图像大小。你的目标是什么?您是否将图像缓存在设备上,以便只下载一次?您是否只以一种尺寸显示它们?您是否要允许用户在滚动视图中查看图像,以便他们可以“放大”它?这些问题的答案将决定您是否要调整图像大小。但是——这完全超出了“我如何让我的堆栈视图工作”问题的范围。
  • 通过调整上面的大小(使用 UIGraphicsImageRenderer)我的意思是对图像进行下采样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
相关资源
最近更新 更多