0

I have an app that lays out differently depending on whether it's in portrait or landscape orientation (specifically, whether height > width or not). On rotation, in viewWillTransitionToSize:withTransitionCoordinator:, I update the constants of some auto layout constraints appropriately. The problem is that at this point the view's frame has not actually rotated yet, so I often get an angry message in the debugger that my constraints can't be satisfied.

My question is this: at what point in the rotation sequence do I modify constraints so that the view's frame has already changed, but I still get the animation alongside the rotation?

This question suggests calling [self.view setNeedsUpdateConstraints] in willAnimateRotationToInterfaceOrientation, but that method is now deprecated. I tried calling that method in viewWillTransitionToSize, but still get the angry messages.

Community
  • 1
  • 1
Tom Hamming
  • 10,577
  • 11
  • 71
  • 145
  • Is that iphone app or universal app ??? Because if you want to change the UI only for iphone in portrait and landscape mode make use of size classes buddy :) No need to add,modify or remove the constraint buddy :) you can handle all in story board itself – Sandeep Bhandari May 03 '16 at 16:56
  • @SandeepBhandari this is a universal app, so there's no way to tell from size classes whether the iPad is in portrait or landscape. – Tom Hamming May 03 '16 at 17:21
  • What happens if the iPad is in landscape, and then the user activates a split screen? Thinking about portrait vs landscape is no longer appropriate. You need to start designing your interface around size classes. – Curmudgeonlybumbly May 03 '16 at 17:32
  • @Curmudgeonlybumbly I know. I'm defining landscape as view width > view height. Size classes can't tell me that specifically. iPad fullscreen is regular size class in both directions. – Tom Hamming May 03 '16 at 19:07

1 Answers1

2

I appear to have solved it. See this article and PureLayout. Basically:

  • Implement a method something like -(void)updateConstraintsForSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
  • In this method, if you've rotated (store the state somewhere), uninstall all your constraints and generate new ones. If you have a coordinator, install them and [self.view layoutIfNeeded] in the coordinator's animateAlongsideTransition block parameter. Otherwise just install and layout.
  • Override viewDidLayoutSubviews and call this method with self.view.bounds.size and nil
  • Override viewWillTransitionToSize:withTransitionCoordinator: and call your method appropriately
Tom Hamming
  • 10,577
  • 11
  • 71
  • 145