Autorotating ViewController after dismissing MPMoviePlayerViewController - ios

Before you vote this question down, note, that I've already tried to implement all the solutions available on stackoverflow. Here is the issue:
My application runs only in portrait mode. The only thing which needs to be in landscape is video player. When a user taps on my TableViewCell this block of code is called:
MPMoviePlayerViewController *moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:videoUrl];
[self presentMoviePlayerViewControllerAnimated:moviePlayer];
After that, I need to give the user the ability to watch video both in portrait and landscape mode. After he is done, everything should get back into portrait mode. I've tried to call this block of code in my AppDelegate.m:
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if ([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]]) {
orientations = UIInterfaceOrientationMaskAllButUpsideDown;
}
return orientations;
}
With it everything is fine except one thing - when the video is over or when the user taps "Done" button while in landscape mode, my view controller appears in landscape mode too.
Besides it, I've tried a lot of other methods - but nothing seems to work.
I'll be glad for any help!

Thanks #Shubham - Systematix for the answer.
All that I had to do was to remove every code related to autorotating except this method in AppDelegate:
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if ([[window.rootViewController presentedViewController] isKindOfClass: [MPMoviePlayerViewController class]])
{
//NSLog(#"in if part");
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else
{
//NSLog(#"in else part");
return UIInterfaceOrientationMaskPortrait;
}
}
When I did it everything worked like a magic!

Related

iOS - UI is not transforming with device rotation change

I am working on orientation and Movie Player. The functionality is as follows:
If I turn on full screen mode of MPMoviePlayer then it should open in landscape mode only.
If I rotate my device to landscape, then it will automatically starts full screen mode of MPMoviePlayer
And again it should come back to portrait mode when I turn off
fullscreen mode of MPMoviePlayer or rotate device to portrait mode.
Now Problem is that, it goes to full screen mode on device rotation to landscape mode
but at the time of come back, The UI is not transforming to portrait mode properly.
This Problem is only with iOS 8.1, 8.2. It is working fine in iOS 7.* and 8.3, 8.4.
Please look at attached screens:
Before Full screen:
After full screen:
Come back to portrait mode:
I have used this code to handle orientation:
allowRotation is Boolean property declared in AppDelegate.h file
//Adding observer for movie player orientation event In App Delegate
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillEnterFullscreenNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillExitFullscreenNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
// Observer methods
- (void) moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
allowRotation = YES;
}
- (void) moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
allowRotation = NO;
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if (([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]] && ![[self.window.rootViewController presentedViewController] isBeingDismissed]) || allowRotation)
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
else{
allowRotation= NO;
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskPortrait;
}
Please help me to resolve this problem.
Do
In your UIViewController, implement
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
// Do the dynamic logic here
}
Don't
Do not ignore the window parameter passed in:
- (UIInterfaceOrientationMask)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window
Your current code is actually not responding to the question: ForWindow.
The general practice is to return
all the possible orientations for a given window (you typically only have a single window per application) in supportedInterfaceOrientationsForWindow
a subset of that list, which can be dynamic, in the view controller supportedInterfaceOrientations.
Example
// App delegate
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
// View controller
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}

How to show MPMoviePlayerController in landscape mode

i am working on a app where I am required to show "MPMoviePlayerController" in landscape mode and portrait mode. But My whole app is required to support Portrait mode only. That is no landscape mode for any view other than for the "MPMoviePlayerController".
I tried few things given over stack overflow. Nothing worked in my case. Feels Stuck in the middle. But I have seen some of the app supporting suck kind of requirements.
I have to implement it for both iOS 6, 7
In my app am using "XCDYouTubeVideoPlayerViewController" for playing videos(playing the youtube videos)
Please Help
I had the same issue, and the following solved the problem:
First you need to allow the Landscape mode either, by checking the checkboxes at Target / General / Deployment Info / Device orientation, and then you have to disable Landscape orientation by code at every ViewController you use in your app.
#pragma mark - Set Supported Device Orientation
//For iOS6
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
//For iOS4 and iOS5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
But don't disable landscape orientation for the XCYoutubeVideoPlayerViewController, so at fullscreen it can rotate to landscape.
I have another solution for this, It will work for all MPMoviePlayerController, below is my code
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)windowx
{
if ([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]] ||
[[self.window.rootViewController presentedViewController] isKindOfClass:NSClassFromString(#"MPInlineVideoFullscreenViewController")])
{
if ([self.window.rootViewController presentedViewController].isBeingDismissed)
{
return UIInterfaceOrientationMaskPortrait;
}
else
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
What we basically do here is we enable Landscape orientation for all MPMoviePlayerController classes which are actually MPInlineVideoFullscreenViewController when you present it for fullscreen.
Hope this helps

How to enable rotation device in only one uiviewcontroller

I have an app that support only portrait mode, but I have an NowPlayingViewController with youtubeView.
I want only this youtubeView support landscape mode (when it's fullscreen)
I found this (in appdelegate.m)
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[self.window.subviews.lastObject class].description isEqualToString:#"<string>"]) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else {
return UIInterfaceOrientationMaskPortrait;
}
}
but I don't know how to set description to my youtubeWiew with this string.
Anyone has solutions?
Rotation has become bit tricky as you can't rotate it forcefully. Though there is a solution, is you need to Customize UINavigationController to add Landscape Rotation, and then present the extra view as modal, it will work.
For more clarification see a sample here I have made for rotations.
I hope it will help you and others.
Cheers.

iOS 7 Interface Orientation

I have an app that is always showed in portrait mode.
But in somewhere i have a media gallery that must support landscape.
The supported orientation by default in the project is portrait. Because of that the gallery is only showed in portrait mode.
If i change the project setting to show in portrait and landscape the gallery works fine but i can't control the other viewControllers to show only in portrait.
I tried several methods like shouldAutoRotate but no one worked.
Any ideia how to solve?
Regards
EDIT:
Solved :)
First i configured the project to support all orientation.
Then i added this method to the AppDelegate.m:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
}
After this what i did was to block orientation in each view controller, less the one i want to have orientation in landscape and portrait.
Code to block orientation (iOS 7):
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}
Thanks to everyone that answered me :)
In my app for iPhone its only support the portrait view only, but as per requirement need to support landscape view only for on view, at that time I use following way and its help me :
In your app delegate .h
#interface PlayWithWSWithLibAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
BOOL flagOrientationAll;
}
#property (assign) BOOL flagOrientationAll;
Add following method in your app delegate .m file
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
//NSLog(#"PlayWithWSWithLibAppDelegate -- supportedInterfaceOrientationsForWindow");
if([UICommonUtils isiPad]){
return UIInterfaceOrientationMaskAll;
}else if(flagOrientationAll == YES){
return UIInterfaceOrientationMaskAll;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
Implement following way in your view which you want to rotate in both portrait and landscape both for iPhone device
-(void)viewWillAppear:(BOOL)animated
{
self.tabBarController.delegate = self;
PlayWithWSWithLibAppDelegate *delegate = (PlayWithWSWithLibAppDelegate *) [[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = YES;
}
}
-(void)viewWillDisappear:(BOOL)animated
{
//NSLog(#"viewWillDisappear -- Start");
PlayWithWSWithLibAppDelegate *delegate = (PlayWithWSWithLibAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = NO;
}
see this post also: How to set one of the screens in landscape mode in iphone?
You have to make another class in the same view Controller where you are presenting your media.
In that you can specify your orientation where it will support only landscape orientation only when you will present your media.
I am giving you an example of my app which supports only in landscape mode but as I took Image picker and it supports only in portrait mode so I changed the orientation for only that view.
#pragma mark - Image PICKER
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait ;
}
#end
Then when I used ImagePicker I used object of the class that i made.
So I define like below.
UIImagePickerController* picker = [[NonRotatingUIImagePickerController alloc] init];
So For Image Picker It showed only in portrait mode.
You just need to change Landscape instead of portrait if you want only Landscape Orientation for your particular view where you want to change it.
Hope this helps you.

iOS 6 MPMoviePlayerViewController and presentMoviePlayerViewControllerAnimated Rotation

In previous iOS versions, our video would rotate automatically but in iOS 6 this is no longer the case. I know that the presentMoviePlayerViewControllerAnimated was designed to do that before but how can I tell the MPMoviePlayerViewController to rotate automatically?
MPMoviePlayerViewController *moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:moviePlayer];
In appdelegate.m :
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if ([[self.window.subviews.lastObject class].description isEqualToString:#"MPMovieView"]) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else {
return UIInterfaceOrientationMaskPortrait;
}
}
Kinda a hack, but works well...
I just ran into the same problem. James Chen's solution is correct, but I ended up doing something a little simpler that also works - overriding application:supportedInterfaceOrientationsForWindow in my app delegate and returning allButUpsideDown if my rootView controller was modally presenting an MPMoviePlayerViewController. Admittedly a hack, and may not be appropriate to all situations, but saved me having to change all my view controllers:
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return [rootViewController.modalViewController isKindOfClass:MPMoviePlayerViewController.class ] ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;
}
This is not limited to MPMoviePlayerViewController. From iOS 6 the autorotation has been changed. see Autorotate in iOS 6 has strange behaviour .
To make your app behave as pre-iOS 6, you have to make the app support all orientations (edit UISupportedInterfaceOrientations in plist), then for all other view controllers which don't support rotation, override this method to return NO:
- (BOOL)shouldAutorotate {
return NO;
}
By default MPMoviePlayerViewController supports all orientations so this should be enough to make it work.

Resources