Deekshith Bellare
Deekshith Bellare

Reputation: 735

Position subviews on superview based on subview count

Subviews need to be placed from the center of super view based on subview count. If subview count is odd, the middle view will be center to the super view and remaining will be placed with respect to it with item spacing. enter image description here

If subview count is even, then subviews are to be placed with offset. enter image description here

Is there any generic solution to solve this without too many conditions and calculations using autolayout?

All subviews are of same size

Upvotes: 0

Views: 121

Answers (2)

paulvs
paulvs

Reputation: 12053

Solution 1: UIStackView

4 subviews

    let totalSubviews = 4
    let stackView = UIStackView()
    view.addSubview(stackView)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .Horizontal
    stackView.distribution = .EqualSpacing
    stackView.alignment = .Center
    stackView.spacing = 10
    stackView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: 0).active = true
    stackView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor, constant: 0).active = true
    stackView.backgroundColor = UIColor.greenColor()

    for _ in 0 ..< totalSubviews {
        let subview = UIView()
        stackView.addArrangedSubview(subview)
        subview.translatesAutoresizingMaskIntoConstraints = false
        subview.backgroundColor = UIColor.redColor()
        subview.heightAnchor.constraintEqualToConstant(50).active = true
        subview.widthAnchor.constraintEqualToConstant(50).active = true
    }

Solution 2: AutoLayout

You can do this generically using AutoLayout.

totalSubviews = 4

4 subviews

totalSubviews = 5

5 subviews

Code

    let totalSubviews = 4
    let spacing = CGFloat(20)
    var subviews = [UIView]()

    var previousSubview: UIView?
    for i in 0 ..< totalSubviews {
        let subview = UIView()
        subviews.append(subview)
        view.addSubview(subview)
        subview.translatesAutoresizingMaskIntoConstraints = false
        subview.backgroundColor = UIColor.redColor()

        view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: spacing))

        if i == 0 {
            view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Left, relatedBy: .Equal, toItem: view, attribute: .Left, multiplier: 1, constant: spacing))
        }
        else if i < totalSubviews {
            view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Left, relatedBy: .Equal, toItem: previousSubview, attribute: .Right, multiplier: 1, constant: spacing))
        }
        if i == totalSubviews - 1 {
            view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Right, relatedBy: .Equal, toItem: view, attribute: .Right, multiplier: 1, constant: -spacing))
        }

        if i != 0 {
            view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Width, relatedBy: .Equal, toItem: previousSubview!, attribute: .Width, multiplier: 1, constant: 0))
        }


        view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 0, constant: 100))

        previousSubview = subview
    }

Upvotes: 1

Maulik Bhuptani
Maulik Bhuptani

Reputation: 616

You will have to take 1 more view inside main view which will include your odd or even number of subviews. Then you need to set Equal width and Equal height constraints between them. So as per your number of subviews and screen size, they all will automatically be positioned.

Upvotes: 0

Related Questions