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

前端 未结 5 565
佛祖请我去吃肉
佛祖请我去吃肉 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 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.

提交回复
热议问题