9

A number of views in a UIStackView are adjusted to fit the stack. The views are initialised with no frame because they are resized by the stack view. Is there a way which I can get the size of the views after they have been resized by the stack view?

Matt Spoon
  • 2,760
  • 5
  • 25
  • 41

3 Answers3

5

The sizes are available after UIStackView.layoutSubviews() finishes. You can subclass UIStackView and override layoutSubviews:

class MyStackView: UIStackView {
    override func layoutSubviews() {
        super.layoutSubviews()
        print("arrangedSubviews now have correct frames")
        // Post a notification...
        // Call a method on an outlet...
        // etc.
    }
}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • 2
    This is not always true, unfortunately. I've encountered many cases where the geometry of the arranged subviews is **not** correct after `super.layoutSubviews()`. In my specific case, I always had to check them on the very next run loop, which is ridiculous. – CIFilter Oct 12 '17 at 20:59
3

Yes. In your View's layoutSubviews(). However you need to force the UIStackView to layout first, using stack.layoutIfNeeded() before using its size.

eg:

public override func layoutSubviews() {
        super.layoutSubviews()

        // Force the UIStackView to layout, in order to get the updated width.
        stack.layoutIfNeeded()

        let tabWidth = stack.arrangedSubviews[0].frame.size.width
}
MihaiL
  • 1,558
  • 1
  • 9
  • 11
0

I think the better way to get a Stackview's subview frame is to use convert.

yourStackView.convert(viewInsideStackView.frame to: parentView)

This will return viewInsideStackView's frame inside parentView's coordinate system.

David T
  • 2,724
  • 1
  • 17
  • 27