以编程方式构建 View 时,我在自动布局方面遇到了一些问题。

有一个垂直的 UIStackView,里面有几个元素,主要是标签和图像。在 stackView 和 imageView 上设置属性后,结果我得到了类似于下面的图像 1 的东西(图像顶部和底部的空白;屏幕尺寸越小,空白越大),而我想得到更类似于图像的东西2(图像周围没有空格)。

1:

ios - 带有 UIImageView 的 UIStackView 上的自动布局 - iOS Swift-LMLPHP

2:

ios - 带有 UIImageView 的 UIStackView 上的自动布局 - iOS Swift-LMLPHP

我正在阅读一些关于如何正确设置 stackView、其分布和对齐方式的教程,因此我的 StackView 属性设置如下:

myStackView.axis = .vertical
myStackView.distribution = .fill
myStackView.alignment = .fill
myStackView.spacing = 12
myStackView.contentMode = .scaleAspectFit

在将 ImageView 添加为排列好的 subview 之前,我设置了:
myImageView.contentMode = .scaleAspectFit
myImageView.autoresizesSubviews = true
myImageView.sd_setImage(with: URL(string: image))
myImageView.setContentHuggingPriority(251, for: .horizontal)
myImageView.setContentHuggingPriority(500, for: .vertical)
myImageView.setContentCompressionResistancePriority(750, for: .horizontal)
myImageView.setContentCompressionResistancePriority(750, for: .vertical)

我没有更改 imageView 上方和下方标签上的 CHP 和 CCRP。

我试图用内容拥抱优先级和内容压缩抵抗优先级进行操作,但它没有改变任何东西。任何想法我做错了什么?

最佳答案

我怀疑这里的问题是拥抱和抗压缩优先级适用于 View 的固有内容大小,而 UIImageView 的固有内容大小是图像的自然大小。但是您希望图像被缩放以适应屏幕的宽度,这意味着(通常)您不希望 ImageView 的大小是其图像的自然大小。因此,拥抱和抗压的优先级不会帮助你。

您需要做的是添加两个约束:

  • 限制 ImageView 的宽度等于堆栈 View 的宽度。您可以在 Storyboard或代码中执行此操作。在代码中:
    myImageView.widthAnchor.constraint(equalTo: myStackView.widthAnchor).isActive = true
    
  • 约束 ImageView 的纵横比以匹配图像的纵横比。如果在运行时更改图像,则需要在代码中执行此操作,如下所示:
    // Instance variable:
    var imageAspectRatioConstraint: NSLayoutConstraint?
    
    // When you set the image:
    imageAspectRatioConstraint?.isActive = false
    imageAspectRatioConstraint = myImageView.widthAnchor.constraint(
        equalTo: myImageView.heightAnchor,
        multiplier: myImageView.image!.size.width / myImageView.image!.size.height)
    imageAspectRatioConstraint!.isActive = true
    

  • 这两个必需的约束将强制 ImageView 精确到正确的高度以完美地包含缩放的图像。

    如果您限制了堆栈 View 的高度以匹配其他 View 的高度(例如,顶级 View ),您可能仍然会遇到问题。 (如果您的堆栈 View 您的顶级 View ,它实际上被限制为填充屏幕。)在这种情况下,堆栈 View 将根据需要拉伸(stretch)或收缩至少一个其排列的 subview 以填充该高度。

    如果所有排列的 subview 都没有灵活的高度,那么自动布局最终可能会破坏 ImageView 的纵横比约束,因此它可以拉伸(stretch) ImageView 以填充所需的空间。或者它可能会拉伸(stretch)一些您不想拉伸(stretch)的其他 View 。

    如果发生这种情况,您有三个选择:
  • 删除强制堆栈 View 填充其他 View 高度的约束。然后自动布局将设置堆栈 View 的高度以准确包含其首选大小的排列 subview (基于约束或内在内容大小)。
  • 降低您想要调整大小以填充所需高度的一个或多个排列 subview 的垂直拥抱和/或压缩阻力优先级。
  • 向堆栈 View 添加“填充”UIView 以吸收额外的高度。将其背景颜色设置为 nil 或 .clear 使其不可见。
  • 关于ios - 带有 UIImageView 的 UIStackView 上的自动布局 - iOS Swift,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42066620/

    10-11 19:49