如何使水平 UIStackView 以 UIImageView 作为其子级包裹高度内容?

Che*_*eng 1 ios swift

我有以下水平UIStackView

  1. 黄色背景
  2. 前导、顶部和尾随与安全区域相同
  3. 对齐方式 = 顶部
  4. 分配=按比例填充

UILabel 作为子项

如果我添加UILabel为其子项,它将自动包裹高度内容,如下所示

在此输入图像描述


UIImage 作为子项

UILabel用3个相同的替换UIImageView

每个都UIImageView具有以下属性

  1. 内容模式 = 宽高比匹配

看起来如下

在此输入图像描述

我想知道,如何使水平UIStackView换行达到其高度内容?

我希望UIStackView's 会包裹UIImageView's 内容高度。因此,我们不会观察到 的任何黄色背景UIStackView

我可以知道,我怎样才能做到这一点?

到目前为止,我已经尝试过玩

  1. UIStackView 和 UIImageView 的内容拥抱优先级
  2. UIStackView 和 UIImageView 的内容抗压缩优先级

还是没能达到我想要的结果。


以下是原图来源,为606x404

在此输入图像描述

Don*_*Mag 6

仅通过情节提要设置无法获得此结果 - 您将需要一些代码。

根据显示所需输出的图像,您希望每个“行”:

  • 有 3 张图片
  • 以原始纵横比显示它们
  • 图像之间的间距较小(例如 4 点)
  • 适合,使宽度和高度保持比例

第一条评论 - 忘记Distribution = Fill Proportionally堆栈视图。

对于此布局,堆栈视图应为:

  • Axis: Horizontal
  • Alignment: Fill
  • Distribution: Fill
  • Spacing: 4

因此,我们需要做的是根据图像的长宽比(高度/宽度)来限制每个 imageView 的长宽比。

这是一个完整的示例...它使用这 6 张图像:

在此输入图像描述 在此输入图像描述 在此输入图像描述 在此输入图像描述 在此输入图像描述 在此输入图像描述

我们还将使用相同的设置(预期)将水平堆栈视图嵌入到垂直堆栈视图中Axis: Vertical

class AdjustStackViewController: UIViewController {
    
    var vStack = UIStackView()
    
    var picNames: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // six images, named "p1" - "p6"
        for i in 1...6 {
            picNames.append("p\(i)")
        }
        
        // vertical stack view
        vStack.axis = .vertical
        vStack.spacing = 4
        
        // use auto-layout
        vStack.translatesAutoresizingMaskIntoConstraints = false
        
        // add it to the view
        view.addSubview(vStack)
        
        // respect safe-area
        let g = view.safeAreaLayoutGuide
        
        NSLayoutConstraint.activate([
            // constrain vStack
            //  Top + 20
            //  Leading and Trailing 0
            vStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            vStack.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            vStack.trailingAnchor.constraint(equalTo: g.trailingAnchor),
        ])
        
        fillStacks()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // re-fill images in new (shuffled) order
        fillStacks()
    }
    
    func fillStacks() -> Void {
        
        // remove existing horizontal stack views (if needed)
        vStack.arrangedSubviews.forEach { v in
            v.removeFromSuperview()
        }
        
        let shuffledImages = picNames.shuffled()

        // two horizontal stack views each with 3 images
        var picNum: Int = 0
        for _ in 1...2 {
            let hStack = UIStackView()
            hStack.spacing = 4
            vStack.addArrangedSubview(hStack)
            for _ in 1...3 {
                // make sure we can load the images
                guard let img = UIImage(named: shuffledImages[picNum]) else {
                    fatalError("Could not load images!")
                }
                // create Image View
                let imgView = UIImageView()
                // set the image
                imgView.image = img
                // proportional constraint based on image dimensions
                imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: img.size.height / img.size.width).isActive = true
                // add to hStack
                hStack.addArrangedSubview(imgView)
                // increment pic number
                picNum += 1
            }
        }

    }
    
}
Run Code Online (Sandbox Code Playgroud)

它看起来是这样的:

在此输入图像描述

当您运行此程序时,每次点击视图时,它都会打乱图像的顺序,以便您可以看到布局如何适应。