Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the frame of a UIStackView subViews

I have created a UIStackView in IB which has the distribution set to Fill Equally. I am looking to get the frame for each subView but the following code always returns (0, 0, 0, 0).

class ViewController: UIViewController {
    @IBOutlet weak var stackView: UIStackView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let pView = UIView()
        let sView = UIView()

        pView.backgroundColor = UIColor.red
        sView.backgroundColor = UIColor.orange

        stackView.addArrangedSubview(pView)
        stackView.addArrangedSubview(sView)
    }

    override func viewDidLayoutSubviews() {
        print(stackView.arrangedSubviews[0].frame)
        print(stackView.arrangedSubviews[1].frame)
    }
}

I would think that a stack view set to fill equally would automatically set the calculate it.

Any help would be appreciated.

like image 930
Wozzer Avatar asked Mar 19 '17 18:03

Wozzer


People also ask

How remove all Subviews from Stackview?

Managing Subviews To remove an arranged subview that you no longer want around, you need to call removeFromSuperview() on it. The stack view will automatically remove it from the arranged subview list.

What's a UIStackView did you use it?

You use a UIStackView to group UI elements together to simplify setting constraints. In other words once you've added objects to the stack view, you constrain the stackview and set attributes on it rather than on each individual element.

What is UIStackView in Swift?

A streamlined interface for laying out a collection of views in either a column or a row.

What is Stackview alignment?

A layout where the stack view aligns the center of its arranged views with its center along its axis. case leading. A layout for vertical stacks where the stack view aligns the leading edge of its arranged views along its leading edge.


1 Answers

After reading over your code I think this is just a misunderstanding of viewDidLayoutSubviews(). Basically it is called when all the views that are descendants of the main view have been laid out but this does not include the subviews(descendants) of these views. See discussion notes from Apple.

"When the bounds change for a view controller's view, the view adjusts the positions of its subviews and then the system calls this method. However, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted. Each subview is responsible for adjusting its own layout."

Now there are many ways to get the frame of the subviews with this being said.

First you could add one line of code in viewdidload and get it there.

    override func viewDidLoad() {
    super.viewDidLoad()

    let pView = UIView()
    let sView = UIView()

    pView.backgroundColor = UIColor.red
    sView.backgroundColor = UIColor.orange

    stackView.addArrangedSubview(pView)
    stackView.addArrangedSubview(sView)
    stackView.layoutIfNeeded()
    print(stackView.arrangedSubviews[0].frame)
    print(stackView.arrangedSubviews[1].frame)

}

OR you can wait until viewDidAppear and check there.

 override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print(stackView.arrangedSubviews[0].frame)
    print(stackView.arrangedSubviews[1].frame)
}
like image 84
agibson007 Avatar answered Sep 23 '22 18:09

agibson007