将 layoutMargins 添加到 UIStackView 中的一个元素

Posted

技术标签:

【中文标题】将 layoutMargins 添加到 UIStackView 中的一个元素【英文标题】:Add layoutMargins to one element in a UIStackView 【发布时间】:2019-03-31 13:17:56 【问题描述】:

我想创建一个包含 3 个元素的垂直堆栈视图。 我只想在第二个和最后一个元素之间留出更多空间。所以我考虑添加到最后一个元素:

mylastelement.layoutMargins = UIEdgeInsets(top:30, left:0,bottom:0, right:0)

但是 layoutmargins 没有应用到我的 stackview 中。有什么简单的方法可以实现(我想避免修改最后一个元素的内部高度)。

编辑:我只是尝试通过这样做来增加其框架内的第二个元素高度(+50):

my2ndElementLabel.sizeToFit()
my2ndElementLabel.frame = CGRect(x:my2ndElementLabel.frame.origin.x,y:lmy2ndElementLabel.frame.origin.y,
                                 width:my2ndElementLabel.frame.width, height:my2ndElementLabel.frame.height + 50)

但它没有效果。

EDIT2:我尝试向我的 UIStackView 添加一个随机视图,但该视图被忽略了!在理解 UIKit 的工作原理时可能遗漏了一些东西?...:

let v = UIView(frame:CGRect(x:0,y:0,width:100,height:400))
v.backgroundColor = .red
myStackView.addArrangedSubview(v)
//...

【问题讨论】:

您是否尝试过在顶部锚点上使用自动布局约束? 你到底是什么意思?实际上我可以限制每个视图从上到下,但我想使用堆栈视图来训练使用它。 奇怪的是,没有办法只为 Stackview 的一个元素添加边距。看起来改变视图的框架没有效果 【参考方案1】:

这是我做的一个扩展,有助于快速实现这样的利润:

extension UIStackView 

    func addArrangedSubview(_ v:UIView, withMargin m:UIEdgeInsets )
    
        let containerForMargin = UIView()
        containerForMargin.addSubview(v)
        v.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            v.topAnchor.constraint(equalTo: containerForMargin.topAnchor, constant:m.top ),
            v.bottomAnchor.constraint(equalTo: containerForMargin.bottomAnchor, constant: m.bottom ),
            v.leftAnchor.constraint(equalTo: containerForMargin.leftAnchor, constant: m.left),
            v.rightAnchor.constraint(equalTo: containerForMargin.rightAnchor, constant: m.right)
        ])

        addArrangedSubview(containerForMargin)
    

【讨论】:

【参考方案2】:

您可以做的是在第二个和第三个元素之间设置自定义间距。

myStackView.setCustomSpacing(30.0, after: my2ndElementLabel)

【讨论】:

【参考方案3】:

同样,您可以将视图的顶部(或底部)锚点相对于嵌入它的任何视图的相应边缘进行约束。丑陋的东西有点品味问题,我发现自动布局约束易于使用且易于推理。

一个来自 Mac OS 而不是 ios 的简单示例:

        let button = ControlFactory.labeledButton("Filter")
        addSubview(button)
        button.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20).isActive = true
        button.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true

这个特定的代码存在于视图初始化器中,并将一个按钮放置在视图的中间,距离底部 20 点。

【讨论】:

【参考方案4】:

我发现自己:看起来 UIStackView 在旧的尺寸调整系统(带有 .frame)上根本不起作用。看来您必须限制高度和宽度,当您添加排列的Subview 时,StackView 会为您限制左/上/右/下位置。

我的第二个视图是一个标签:我希望在文本下方留出 40 的边距。所以我首先将标签高度计算到它的 .frame 属性中,并将高度限制在 frame.height + 40(= my margin)

labelDesc.sizeToFit()
labelDesc.heightAnchor.constraint(equalToConstant:40).isActive = true

我发现我自己的解决方案非常丑陋。我确信 UIKit 提供了一种更好的方法来实现这样一个简单的目标,而不必制作这些 DIY 解决方案。因此,如果您习惯使用 UIKit,请告诉我是否有更好的解决方案。

【讨论】:

【参考方案5】:

考虑根据需要在 Stack View 中插入大小正确的 UIView 来添加“边距”。

如果您需要 2 个特定元素之间的 40px 边距...添加一个高度约束为 40px 的 UIView。分配clearColor 背景使其不可见。

您可以将 IBOutlets 添加到此视图并将其隐藏,就像您在堆栈视图中的任何其他项目一样。

【讨论】:

以上是关于将 layoutMargins 添加到 UIStackView 中的一个元素的主要内容,如果未能解决你的问题,请参考以下文章

imageView.layoutMargins = UIEdgeInsets.zero 在 UICollectionViewCell 中没有效果

使用自动布局设置 layoutMargins

iOS 8和layoutMargin中的自定义UITableViewCells

以编程方式为 UITableViewCell 设置 LayoutMargins - iOS 7 替代方案

UIStackView 调整我的视图大小

UISTackView没有有用的ReadableContentGuide