MPMoviewPlayerController fullscreen playback rotation with underlying UIViewController with portrait mode only (rotation disallowed)

前端 未结 5 562
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-05 01:35

Hallo,

I have a simple application, which does contain UITabBarController with two UIViewControllers. Both UIViewControllers are portrait only (no rotation allowed).

相关标签:
5条回答
  • 2020-12-05 01:50

    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.....

    0 讨论(0)
  • 2020-12-05 01:54

    The MPMoviePlayerViewController has its own function to present videos modally:

    NSURL *videoURL = [NSURL fileURLWithPath:video.path];
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
    
    //Calls for movie playback once video is finished
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayBackDidFinish:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification
                                               object:moviePlayer];
    playerView = [[MPMoviePlayerViewController alloc]init];
    [moviePlayer setControlStyle:MPMovieControlStyleFullscreen];
    [playerView setView:moviePlayer.view];
    
    [moviePlayer.view setFrame: self.view.bounds];  
    [self presentMoviePlayerViewControllerAnimated:playerView];
    
    [moviePlayer play];
    NSLog(@"playing video view");
    
    0 讨论(0)
  • 2020-12-05 01:57

    You can try to present new UIViewController (with shouldAutorotate YES) modally and add __moviePlayer.view into this controller when it sends MPMoviePlayerWillEnterFullscreenNotification. Do the opposite when moviePlayer exits fullscreen.

    0 讨论(0)
  • 2020-12-05 02:02

    Register for MPMoviePlayerWillExitFullscreenNotification and MPMoviePlayerWillEnterFullscreenNotification in app delegate and handle the orientation using an instance variable.

    
    -(void)moviePlayerFullScreen:(NSNotification *)notification
    {
        if ([notification.name isEqualToString:@"MPMoviePlayerWillEnterFullscreenNotification"]) {
    
            self.supportedOrientation=UIInterfaceOrientationMaskAll;
    
        }
        else if ([notification.name isEqualToString:@"MPMoviePlayerWillExitFullscreenNotification"])
        {
            self.supportedOrientation=UIInterfaceOrientationMaskPortrait;
    
        }
     }
     - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window  {
        return self.supportedOrientation;
    }
    
    
    0 讨论(0)
  • 2020-12-05 02:07

    I have a very similar situation. My app is portrait-only. But I need to show full-screen videos in any orientation, and then get back to the portrait orientation, after the user quits full-screen mode.

    Split's method doesn't work for me, because I would like to let user watch the video in fullscreen and embedded, and switch between modes, not loosing the play position, and without any pauses.

    I found this workaround:

    First, I have a root UINavigationController subclass, that receives all messages regarding rotation.

    I forbid the rotation in this controller with:

    - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation {
        return (UIInterfaceOrientationPortrait == toInterfaceOrientation);
    }
    

    I am overriding the

    - (id) initWithRootViewController:(UIViewController *)rootViewController; method. 
    

    Adding the support for device orientation modifications:

    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(receivedRotate:) name: UIDeviceOrientationDidChangeNotification object: nil];
    

    Now I have a handler receivedRotate: - that catches all the device rotations in spite of not auto-rotating to any orientations except portrait:

    - (void) receivedRotate:(NSNotification*) notify {
        if(isVideoFullscreen) {
            UIDeviceOrientation toInterfaceOrientation = [[UIDevice currentDevice] orientation];
            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:0.4];
            [UIView setAnimationCurve:2];
    
            if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft){
                self.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
                self.view.bounds = CGRectMake(0, 0, 1024, 768);
            } else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
                self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; 
                self.view.bounds = CGRectMake(0, 0, 1024, 768);            
            } else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
                self.view.transform = CGAffineTransformMakeRotation(M_PI);
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortraitUpsideDown];
                self.view.bounds = CGRectMake(0, 0, 768, 1024);
            } else if(toInterfaceOrientation == UIInterfaceOrientationPortrait) {
                self.view.transform = CGAffineTransformMakeRotation(0);
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
                self.view.bounds = CGRectMake(0, 0, 768, 1024);
            }
    
            [UIView commitAnimations];
        }
    
    }
    

    I just check the rotations of the device, and rotate my view accordingly.

    Then - how do the root controller knows, when the video is fullscreen? Just add two other message handlers to the init:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
    

    And the handlers themselves:

    - (void) willEnterFullscreen: (NSNotification *) notify {
        isVideoFullscreen = YES;
    }
    
    - (void) willExitFullscreen: (NSNotification *) notify {
        self.view.transform = CGAffineTransformMakeRotation(0);
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
        self.view.bounds = CGRectMake(0, 0, 768, 1024);    
        isVideoFullscreen = NO;
    }
    

    When exiting fullscreen - we restore the portrait orientation. So, this works for me, hope it will help someone.

    0 讨论(0)
提交回复
热议问题