There are a multitude of questions here relating to locking movie playback into landscape mode, or supporting landscape playback of movies using MPMoviePlayerViewController or MPMoviePlayerController. I already have landscape/portrait functionality, and I don't want to lock the playback to either mode.
What I have is code which uses MPMoviePlayerViewController as the docs suggest, essentially:
MPMoviePlayerViewController* movieViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:url]; [parentViewController presentMoviePlayerViewControllerAnimated:movieViewController];
My app is mostly locked to portrait mode, but this code presents the movie controller modally in its own view, and supports both portrait and landscape orientations. All of which is very nice.
Here is my problem though. 99% of the videos I will be presenting are landscape videos, and the above code starts the movie playback in portrait mode, because the user is (likely) holding the device in portrait mode.
What I want is the behaviour of the native YouTube app; that when you present the movie controller, it first presents in landscape mode, which will prompt the user to change their device's orientation. If they later on want to rotate it back to portrait they are allowed to. When the movie is done (or dismissed), the movie view controller will be dismissed, and the device should be in portrait mode.
It seems impossible to hide the status bar properly (it's tied to the full screen controls regardless of the state of 'hideStatusBar' before launching the movie), so it seems that getting the status bar to be in the right place also needs to be a part of this.
Edited to add debugging notes for status bar orientation:
If I call setStatusBarOrientation:UIInterfaceOrientationLandscapeRight
before launching the movie, the status bar is in the right place, but the system no longer calls shouldAutorotateToInterfaceOrientation
in the same way.
If I don't call setStatusBarOrientation
, prior to the movie appearing I get the following sequence of calls:
shouldAutorotateToInterfaceOrientation(Portrait) shouldAutorotateToInterfaceOrientation(Portrait) shouldAutorotateToInterfaceOrientation(Portrait) shouldAutorotateToInterfaceOrientation(Right) shouldAutorotateToInterfaceOrientation(Portrait)
I answer YES only to the Right, and the movie launches in LandscapeRight, but with the status bar in the wrong place. Subsequent changes of device orientation generate exactly the shouldAutorotateToInterfaceOrientation
calls you'd expect (e.g. if I rotate to Portrait, it asks me if it's okay to rotate to Portrait).
If I do call setStatusBarOrientation:UIInterfaceOrientationLandscapeRight
, I get the following sequence:
shouldAutorotateToInterfaceOrientation(Right) shouldAutorotateToInterfaceOrientation(Right)
Both of which I answer YES to. The status bar is in the right place, but I no longer get an calls to shouldAutorotateToInterfaceOrientation
asking about Portrait mode. So if I rotate the device to Right, then back to Portrait, then back to Right, I see it call shouldAutorotateToInterfaceOrientation(Right)
twice. Even stranger, if I rotate it all the way around to the Left orientation, I do get shouldAutorotateToInterfaceOrientation(Left)
and from then on everything works fine. Which is most annoying.
I think it must be a bug on the iOS side, and that's why the YouTube app doesn't use the animated UI rotation effects. Instead it hides the full screen controls, including the status bar, rotates invisibly in the background, and then re-shows the controls.