UIStackView儿童等间距(周围和之间)

时间:2015-10-22 21:29:03

标签: ios objective-c swift uistackview

如何在视图之间使用与填充和间隙相同的空间的UIStackView?

如何实现此布局:

Expected layout

当这个不适合我时:

No good layout

这两个都没有:

enter image description here

我只需要将周围的视图空间与视图之间的空间相同。 为什么这么难?

重要 我正在使用my fork TZStackView来支持iOS 7.所以对我来说没有layoutMargins :(

3 个答案:

答案 0 :(得分:7)

我知道这是一个较旧的问题,但我解决它的方法是在我的堆栈的开头和结尾添加两个大小为零的UIViews,然后使用.equalSpacing发行版。

注意:这只保证沿着堆栈视图主轴的间距相等(即我的例子中的左右边缘)

let stack = UIStackView()

stack.axis         = .horizontal
stack.alignment    = .center
stack.distribution = .equalSpacing

// add content normally
// ...

// add extra views for spacing
stack.insertArrangedSubview(UIView(), at: 0)
stack.addArrangedSubview(UIView())

enter image description here

答案 1 :(得分:6)

使用UIStackView几乎可以实现您想要的效果。当你在UIStackView中的UIViews上设置一些约束时,你可以想出这个:

enter image description here

这缺少您要查找的左右填充。问题是UIStackView在向其添加视图时会添加自己的约束。在这种情况下,您可以添加topbottom约束来获取垂直填充,但是当您尝试为正确填充添加trailing约束时,UIStackView会忽略或覆盖那个约束。有趣的是,为左边填充添加了leading约束。

但是,对UIStackView's排列的子视图设置约束并不是您想要做的。使用UIStackView的重点是给它一些观点,让UIStackView处理其余的观点。

实现你想要做的事实际上并不太难。以下是UIViewController的示例,其中包含可以处理所有边的填充的自定义堆栈视图(我使用SnapKit来表示约束):

import UIKit
import SnapKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let padding: CGFloat = 30

        let customStackView = UIView()
        customStackView.backgroundColor = UIColor(white: 0, alpha: 0.1)
        view.addSubview(customStackView)
        customStackView.snp_makeConstraints { (make) -> Void in
            make.top.left.equalTo(padding)
            make.right.equalTo(-padding)
        }

        // define an array of subviews
        let views = [UIView(), UIView(), UIView()]

        // UIView does not have an intrinsic contentSize
        // so you have to set some heights
        // In a real implementation the height will be determined
        // by the views' content, but for this example
        // you have to set the height programmatically
        views[0].snp_makeConstraints { (make) -> Void in
            make.height.equalTo(150)
        }
        views[1].snp_makeConstraints { (make) -> Void in
            make.height.equalTo(120)
        }
        views[2].snp_makeConstraints { (make) -> Void in
            make.height.equalTo(130)
        }

        // Iterate through the views and set the constraints
        var leftHandView: UIView? = nil
        for view in views {
            customStackView.addSubview(view)
            view.backgroundColor = UIColor(white: 0, alpha: 0.15)

            view.snp_makeConstraints(closure: { (make) -> Void in
                make.top.equalTo(padding)
                make.bottom.lessThanOrEqualTo(-padding)
                if let leftHandView = leftHandView {
                    make.left.equalTo(leftHandView.snp_right).offset(padding)
                    make.width.equalTo(leftHandView)
                } else {
                    make.left.equalTo(padding)
                }
                leftHandView = view
            })
        }

        if let lastView = views.last {
            lastView.snp_makeConstraints(closure: { (make) -> Void in
                make.right.equalTo(-padding)
            })
        }
    }
}

这会产生以下结果:

enter image description here

答案 2 :(得分:1)

对于那些一直在这里寻找解决这个问题的人。我发现最好的方法(在我的情况下)是使用父UIView作为背景和填充,如下所示:

enter image description here

在这种情况下,UIStackViewUIView的边缘一致,并带有填充,并将子视图与间距分开。