以编程方式向UIStackView添加子视图

10

我正在尝试实现一个表格视图单元,显示代表家庭设施(例如毛巾、wifi、洗衣房等)的一系列图标。单元格可能会显示大量设施(取决于家中拥有多少设施),因此我将最多显示三个,并指示如果超过三个,则可以点击单元格查看更多。这是它应该看起来的样子(来自Airbnb的应用程序):

enter image description here

我试图通过在表格视图单元中动态添加UIImageViews到UIStackView来完成此操作。我使用了alignment设置为“填充”和distribution设置为“平均间距”的UIStackView,其想法是无论我添加多少图标,堆栈视图都会均匀地排列它们。

我在Storyboard中设置了stack view。它与其内容视图的顶部、底部、左侧和右侧边缘约束相关联,以便它填充表格视图单元,直到边缘。

这是我尝试使用的代码动态向单元格添加UIImageViews的方式。请注意,“amenities”是一个字符串数组,等于我的图像资源文件夹中图标的名称:

        cell.stackView.backgroundColor = UIColor.greenColor()
        var i = 0
        while (i < amenities.count && i < 4) {
            if (i < 3) {
                let imageView = UIImageView(image: UIImage(named: amenities[i]))
                imageView.contentMode = .ScaleAspectFit
                imageView.translatesAutoresizingMaskIntoConstraints = false
                imageView.backgroundColor = UIColor.blueColor()

                // Add size constraints to the image view
                let widthCst = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 50)
                imageView.addConstraint(widthCst)

                // Add image view to stack view
                cell.stackView.addSubview(imageView)
            } else {
                // Add a label to the stack view if there are more than three amenities
                let label = UILabel()
                label.text = "\(amens.count - i) more"
                label.textAlignment = NSTextAlignment.Left
                cell.stackView.addSubview(label)
            }
            i++
        }
图像视图的背景是蓝色的,而堆栈视图的背景颜色是绿色的。下面是一个例子,其中房屋有三种设施: enter image description here 所有图像视图似乎都被推到屏幕左侧,并且它们从上到下填充了单元格的内容视图,即使堆栈视图固定在内容视图边缘。看起来没有绿色,因此堆栈视图似乎未保持固定状态到单元格的边缘。您知道出了什么问题吗?

5
使用 addArrangedSubview - dan
1个回答

28
正如 Dan 在评论中所说的那样,使用 addArrangedSubview 方法添加一个子视图,UIStackView 会自动布局它。
然而需要注意的是:如果你从 UIStackView 的 arrangedSubviews 数组中移除了一个视图,则它仍然是一个子视图。根据 UIStackView 文档所述:
堆栈视图确保其 arrangedSubviews 属性始终是其 subviews 属性的子集。具体来说,堆栈视图强制执行以下规则:
• 当堆栈视图将一个视图添加到其 arrangedSubviews 数组时,如果该视图尚未作为子视图添加,则同时将其添加为子视图。
• 当从堆栈视图中删除一个子视图时,堆栈视图也会从 arrangedSubviews 数组中将其删除。
• 从 arrangedSubviews 数组中删除一个视图不会将其作为子视图删除。堆栈视图不再管理该视图的大小和位置,但该视图仍然是视图层次结构的一部分,如果可见,则在屏幕上呈现。
最好的做法是始终先查看文档。

4
从文档中值得注意的一点是:“UIStackView是UIView的一个非渲染子类。它不提供任何自己的用户界面,而是仅管理其排列视图的位置和大小。因此,一些属性(如backgroundColor)对堆栈视图没有影响。”这就是为什么kcstricks看不到她的绿色背景的原因。 - rob mayoff
谢谢@robmayoff!我实际上在文档中没有深入了解。我真是太丢人了! - Alex Popov
非常抱歉回复晚了!我终于有时间回到应用程序并尝试了一下,结果完美无缺!谢谢你!也感谢@robmayoff提供的有用提示。 - kcstricks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接