Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equal Spacing for several views using SnapKit

How can I use snap kit to achieve the same spacing between views (and the superview for firstSubview.left and lastSubview.right) like for the bars in the picture below (and using SnapKit instead of stack view or so)?

enter image description here

Thanks!

like image 350
Pascal Avatar asked Jul 16 '26 06:07

Pascal


1 Answers

If you don't want to or cannot use a UIStackView you can achieve the same layout by setting centerX constraints to the superview and add different multipliers for each subview:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .gray

        let containerView = UIView()
        containerView.backgroundColor = .lightGray
        view.addSubview(containerView)

        let numberOfLines = 8
        for _ in 0..<numberOfLines {
            let lineView = UIView()
            lineView.backgroundColor = .cyan
            containerView.addSubview(lineView)
        }

        containerView.snp.makeConstraints { (make) in
            make.top.equalTo(60)
            make.left.equalTo(20)
            make.right.equalTo(-20)
            make.height.equalTo(150)
        }

        let centerXFactor: CGFloat = 2 / CGFloat(containerView.subviews.count + 1)
        containerView.subviews.enumerated().forEach { (index, lineView) in
            lineView.snp.makeConstraints({ (make) in
                make.top.bottom.equalTo(0)
                make.width.equalTo(4)
                make.centerX.equalTo(containerView).multipliedBy(CGFloat(index + 1) * centerXFactor)
            })
        }
    }
}

The only "magic" here is how to calculate the lineViews centerX multipliers: You know that when you have 8 lineViews you'll have 9 spaces inbetween them (also counting the spaces between the containerView's left and right edge and the first and last lineView).

To place a lineView's centerX on the right edge of the containerView, you would have to set its centerX constraint to the containerView's centerX constraint multiplied by 2 (You don't want to do that, but you need that value for the calculation).

Now, to get the multiplier for each lineView you divide 2 by the number of lineViews plus 1 (remember that we have one more space than we have lineViews). And then you set the centerX constraints on the lineViews as follows (for 8 lineViews the multiplier is 2 / 9 = 0.2222):

(pseudo code)
lineView 1: centerX = containerView.centerX multiplied by (1 * 0.2222)
lineView 2: centerX = containerView.centerX multiplied by (2 * 0.2222)
lineView 3: centerX = containerView.centerX multiplied by (3 * 0.2222)
etc.

Which gives you this:

enter image description here

like image 152
joern Avatar answered Jul 17 '26 20:07

joern



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!