内置UIImageView的UIStackView上的自动布局 - iOS Swift

时间:2017-02-06 11:26:22

标签: ios swift uiimageview autolayout uistackview

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

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

1:

White spaces around image

2:

No white spaces around image

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

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

在我将它添加为排列的子视图之前在ImageView上,我设置了:

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。

我试图操纵内容拥抱优先级和内容压缩阻力优先但它没有改变任何东西。我有什么想法吗?

1 个答案:

答案 0 :(得分:10)

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

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

  • 将图像视图的宽度限制为等于堆栈视图的宽度。您可以在故事板或代码中执行此操作。在代码中:

    myImageView.widthAnchor.constraint(equalTo: myStackView.widthAnchor).isActive = true
    
  • 限制图像视图的宽高比以匹配图像的宽高比。如果在运行时更改图像,则需要在代码中执行此操作,如下所示:

    // 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
    

这两个必需的约束将强制图像视图完全包含缩放图像的正确高度。

如果您限制堆栈视图的高度以匹配其他视图的高度(例如,您的顶级视图),则可能仍会遇到麻烦。 (如果您的堆栈视图 是您的顶级视图,则它实际上受限于填充屏幕。)在这种情况下,堆栈视图将根据需要拉伸或缩小其至少一个已排列的子视图填补那个高度。

如果排列的子视图都没有灵活的高度,那么自动布局可能会最终破坏图像视图的宽高比约束,因此它可以拉伸图像视图以填充所需的空间。或者它可能会拉伸你不想拉伸的其他视图。

如果发生这种情况,您有三种选择:

  • 删除强制堆栈视图填充其他视图高度的约束。然后,自动布局将设置堆栈视图的高度,以精确包含其首选大小的排列子视图(基于约束或内在内容大小)。

  • 降低要调整大小以填充所需高度的一个或多个已排列子视图的垂直拥抱和/或压缩阻力优先级。

  • 在堆栈视图中添加“填充”UIView以吸收额外的高度。将其背景颜色设置为nil或.clear,使其不可见。