问题
I have an iPhone application (iOS6+) that supports all interface orientations. However, only landscape orientation should be supported when an MPMoviePlayerController is playing a video fullscreen.
I found the following solution on Stack Overflow and it works.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
...
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (self.landscapeOnlyOrientation) {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
return UIInterfaceOrientationMaskAll;
}
- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
self.landscapeOnlyOrientation = YES;
}
- (void)moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
self.landscapeOnlyOrientation = NO;
}
However, an annoying problem persists, namely that if the video exits fullscreen in portrait orientation (after playing in forced landscape), the underlying view doesn't rotate back. I have to manually rotate the device to landscape and back to portrait to trigger updating of the orientation. Is there some way I can trigger this kind of update programatically?
The following set of screenshots should illustrate what I mean:
NB: For various reasons, using MPMoviePlayerViewController is not possible.
回答1:
Hi all I had same problem I resolved it -
Here is my complete code....
You need to first change in appdelegate:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[[NowPlaying sharedManager] playerViewController] allowRotation])//Place your condition here
{
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
Register Notifications for the full screen control:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:)
name:MPMoviePlayerWillExitFullscreenNotification
object:nil];
Then add line of code in the player controller:
- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^
{
self.allowRotation = YES;
});
}
- (void)moviePlayerWillExitFullscreenNotification:(NSNotification *)notification
{
self.allowRotation = NO;
[self.moviePlayerController setControlStyle:MPMovieControlStyleNone];
dispatch_async(dispatch_get_main_queue(), ^
{
//Managing GUI in pause condition
if (self.currentContent.contentType == TypeVideo && self.moviePlayerController.playbackState == MPMoviePlaybackStatePaused)
{
[self.moviePlayerController pause];
if (self.playButton.selected)
self.playButton.selected = NO;
}
self.view.transform = CGAffineTransformMakeRotation(0);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
self.view.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
});
}
This code is tested in iOS6 and iOS7 working fine. Thanks :)
Please let me know if there is any question.....
回答2:
You need to subclass and provide landscape as supported interface orientation.
@interface MyMovieViewController : MPMoviePlayerViewController
@end
@implementation MyMovieViewController
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
@end
回答3:
You could try to "force" an orientation refresh to let the system handle the correct orientation for you:
- (void)forceOrientationRefresh
{
// Force orientation refresh
[self presentModalViewController:[UIViewController new]
animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
It's hack-ish but it works.
回答4:
This might sound crazy but, can you try saving locally the last orientation before opening the video view controller and then using application:supportedInterfaceOrientationsForWindow:
to return the saved orientation and force the view controller to stay on it and not rotate.
回答5:
You can change your orientation programmatically like this
-(void)viewDidAppear:(BOOL)animated
{
if(UIDeviceOrientationIsPortrait(self.interfaceOrientation)){
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeLeft );
}
}
}
And don´t forget to add #import <objc/message.h>
回答6:
I think you can register your viewcontroller for device orientation and call viewcontroller's orientation method forcefully.
回答7:
You use supportedIterfaceOrientationsForWindow then look for: MPInlineVideoFullscreenViewController. It is a bit tricky to find right view controller but it works.
Here is the sample code:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if ([NSStringFromClass([self.window.rootViewController.presentedViewController.presentedViewController class]) isEqualToString:@"MPInlineVideoFullscreenViewController"]){
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskLandscape;
}
回答8:
you need to add this code for iOS7 it works perfect and simple
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
.... creating a player
MPMoviePlayerViewController *mp =[[MPMoviePlayerViewController alloc] initWithContentURL:url];
...make settings and present it
[self presentMoviePlayerViewControllerAnimated:mp];
来源:https://stackoverflow.com/questions/21911151/forcing-landscape-orientation-on-fullscreen-mpmovieplayercontroller-prevents-cor