12

We have a MainViewController with a tableView, and it presents a new modalViewController.

The MainViewController is restricted to portrait only, and the modalViewController can rotate.

The problem is in iOS8, that when the modalViewController rotates, the callback method of rotation in iOS8 in MainViewcontroller is called - - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

Thus, the UITableView is getting its data reloaded, which is a behaviour we don't want.

Can we prevent this feature of iOS 8, and not rotate the presenting UIViewController?

oren
  • 3,159
  • 18
  • 33
  • Is the callback being called at all on iOS7? Because according to the [documentation](https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIContentContainer_Ref/index.html#//apple_ref/occ/intfm/UIContentContainer/viewWillTransitionToSize:withTransitionCoordinator:) it was introduced on iOS8 – Leonardo Feb 11 '15 at 11:20
  • @Leonardo in iOS7 everything is fine, this is indeed a feature of iOS8 that I don't want... – oren Feb 11 '15 at 13:15
  • override it and make it do nothing – Leonardo Feb 11 '15 at 13:17
  • @Mathieu No... Just found that it happens only with modalViewController, when explicitly setting constraints... – oren Feb 25 '15 at 07:35
  • 1
    @Mathieu please see my answer below, I did example project in git. – oren Feb 26 '15 at 12:11

3 Answers3

13

So after long days of searching and investigating, I finally came up with a possible solution.

First of all, I can use navigation controller and push the viewController instead of presenting it, but it breaks my code and just isn't so true.

The second thing I can do is not setting constraints. I still can use autolayout, but if I don't set constraints, and let the default constraints to be set, the tableView doesn't get reloaded. of course this is also isn't very smart thing to do, as I have many elements in my viewController.

Finally, I figured out that I can show this "modal" viewController in another UIWindow. I create UIWindow and set the modalViewController as its rootViewController.

I put some example project in git: https://github.com/OrenRosen/ModalInWindow

Hope it will be helpful.

oren
  • 3,159
  • 18
  • 33
0

I did something similar with a navigation controller, that wouldn't rotate unless the top pushed controller does rotate.

In your case check if the main controller is presenting another controller. If it isn't then just reject rotation, otherwise return whatever the presented controller returns for the rotation method.

As for your table view, it shouldn't get reloaded because of rotations.

Rivera
  • 10,792
  • 3
  • 58
  • 102
  • I need to present modally the viewController, and not push viewController, I already know that when pushing viewController it doesn't get rotated, please read the comments and other answers before you post a question. And when presenting modally in iOS8, when the presented viewController rotates, all the screen rotates and it affecting also the presentingViewController. Thanks anyway – oren Feb 26 '15 at 12:11
  • I read the question, and know you want to present, not push. I just gave you an example with pushing controllers that could work with presented controllers as well. – Rivera Feb 27 '15 at 12:49
  • Thanks, I appreciate it. But I tried all the possible solutions out there and didn't work for me. It just looks like the presenting viewController doesn't rotate, but it does, its view size do change. Anyway, I resolved it with an extra UIWindow. meantime it works like a charm, but I still waits for some unexpected behavior... :) – oren Feb 27 '15 at 13:04
0

In iOS 8 the view that rotates when you change the device orientation is the first view added to the UIWindow. So, if you save a reference to it in your presentedController, you can overwrite the shouldAutorotate and supportedInterfaceOrientations values.

Luca D'Alberti
  • 4,749
  • 3
  • 25
  • 45