ios - 在 UIStackView 上使用 UIImageView 自动布局 - iOS Swift

标签 ios swift uiimageview autolayout uistackview

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

有一个垂直的 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

在我将其添加为已排列的 subview 之前,在 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。

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

最佳答案

我怀疑这里的问题是拥抱和抗压缩优先级适用于 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 - 在 UIStackView 上使用 UIImageView 自动布局 - iOS Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42066620/

相关文章:

ios - Realm 关系的谓词,检查列表是否为空

swift - 扩展名为 : What is happening here? 的自动类型转换

swift - 在 Ubuntu 上使用 Swift 创建 PDF 文件

ios - SKProduct 崩溃 - 仅在商店版本的应用程序中

ios - 我想让我的 UIImage 使用 resizableImageWithCapInsets 在 iPhone 和 iPad 上看起来一样

iphone - UIImageview 在 iOS7 中没有动画,但在 iOS6 中运行良好

c# - Xamarin Forms webview 未在设备上显示

ios - 是否有将数字转换为十六进制字符串的快速 native 函数?

ios - 使用 AutoLayout 缩小 UIImageView 高度

ios - (iOS) 从 Documents 文件夹中读取 plist - 我得到正确的路径但无法加载字典