Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Autolayout - Frame size not set in viewDidLayoutSubviews

Tags:

I'm working on a keyboard for iOS 8 using Autolayout to place the buttons on the view.
When I'm changing the layout using constraints, everything is appearing correctly on the screen, but when I want to know the view's frame size, I don't get the right size.

For example: I press a key, the keyboard layout changes and layouts everything according to my constraints. Then I want to know the size of any button on the screen - I do that in "viewDidLayoutSubviews" and get that result in the console:

2014-10-29 12:27:09.088 Keyboard[2193:60674] view did layout subviews
2014-10-29 12:27:09.088 Keyboard[2193:60674] {{inf, inf}, {0, 0}}

The button has the correct size and correct position, but when trying to get its frame the size is not set.

Where do I have to put my code when it is not working in viewDidLayoutSubviews?

I found a lot of questions on stackoverflow and other websited, but none of them covered my question.

like image 630
beeef Avatar asked Oct 29 '14 11:10

beeef


2 Answers

I encountered a very similar issue (upvoted question) and found beeef's answer to point in the right direction. Given that Apple's documentation says not to call layoutSubviews() directly, I instead did as follows (where mySubView is a direct subview of self.view):

override func viewDidLayoutSubviews() {
    // self.view's direct subviews are laid out.
    // force my subview to layout its subviews:
    self.mySubView.setNeedsLayout()
    self.mySubView.layoutIfNeeded()

    // here we can get the frame of subviews of mySubView
    // and do useful things with that...
}

Just FYI, in my case mySubView is a UIScrollView, and I need to get the frame of one of its subviews, such that I can set the contentOffset accordingly before the view appears. I'm not sure whether viewDidLayoutSubviews() is the best place to do this, but it ensures that mySubView has been laid out.

like image 158
rene Avatar answered Oct 25 '22 07:10

rene


Yes! I solved that problem myself.

I'm not sure if I got it right, but that's what I think:

  • viewDidLayoutSubviews get's called every time when the layout is changing
  • viewDidLayoutSubviews get's called when the direct subviews of my view did layout, but the subviews of that subviews did not layout at that moment, so you can't get the size of them.

My solution now was to manually call .layoutSubviews() on all my views which contains all my buttons of my keyboard. After that, I get the size of all the buttons I want.

Please correct me if I'm wrong.

like image 33
beeef Avatar answered Oct 25 '22 06:10

beeef