简体   繁体   中英

presentViewController changes the orientation of the controller

I want to play a video from a view controller. When I present it, it is presented like it is a portrait orientation, so view turns. It only happens on iPhones,not the iPads.

There is a ViewController > MyItemsController > VideoController

在此处输入图片说明

When I close the VideoController, parent controller (MyItemsController) of the video controller is like:

在此处输入图片说明

Storyboard of the view controller is:

在此处输入图片说明

And the code is:

-(void)playMoviesForItems:(NSArray *)shopItems{
    VideoPlayerViewController* moviePlayer = [self.storyboard instantiateViewControllerWithIdentifier:@"videoPlayerController"];
    moviePlayer.modalPresentationStyle = UIModalPresentationCurrentContext;
    moviePlayer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self presentViewController:moviePlayer animated:NO completion:nil];
}

I moved the code into app delegate :

-(void)playMoviesForItems:(NSArray *)shopItems{
VideoPlayerViewController* mp = [[self getStoryboard] instantiateViewControllerWithIdentifier:@"videoPlayerController"];
[mp playMoviesForItems:shopItems];
[self pauseBackgroundMusic];

[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:mp animated:YES completion:NULL];
}

This time, everything seem to be ok. Movie is playing, I can hear the sound, but cannot see the video. Why? 在此处输入图片说明

While the accepted answer was down voted since it does not answer the question, here's something that works on iOS9 :

The method that gets called when the ViewController is presented (modally) is preferredInterfaceOrientationForPresentation . This method must return an orientation.
You should check the presenter's orientation and return it as preferred:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
        UIInterfaceOrientation topOrientation = self.navigationController.visibleViewController.interfaceOrientation;
        UIInterfaceOrientation presentingOrientation = self.presentingViewController.interfaceOrientation;

        return   presentingOrientation ? presentingOrientation : topOrientation ? topOrientation : UIInterfaceOrientationLandscapeLeft;
}

topOrientation contains the visible view controller's orientation, while the presentingOrientation is the orientation of the called to presentViewController:animated... In general, I advise you to create a "base" UIViewController class, and inherit from it. This way all of your view controllers will benefit from this code.

I had this exactly same problem a few minutes ago.

What happened to me is that I was trying to present the new ViewController with a another ViewController which wasn't in the hierarchy, it only had it's view added as a subview of a third ViewController in the hierarchy. To fix the problem, I just made this last ViewController present the new one.

Example of what not to do:

UIViewController *secondController = [UIViewController alloc] init];
[rootViewController presentViewController:secondController animated:NO completion:nil];

UIViewController *controllerOutsideHierarchy = [UIViewController alloc] init];
[secondController.view addSubview:controllerOutsideHierarchy.view];

[controllerOutsideHierarchy presentViewController:thirdController animated:NO completion:nil];

Example of what should be done instead:

UIViewController *secondController = [UIViewController alloc] init];
[rootViewController presentViewController:secondController animated:NO completion:nil];

UIViewController *controllerOutsideHierarchy = [UIViewController alloc] init];
[secondController.view addSubview:controllerOutsideHierarchy.view];

[secondController presentViewController:thirdController animated:NO completion:nil];

Hope this helps!

Make sure to add these two in the child view controller:

- (UIInterfaceOrientationMask) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

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

you must add the methods below , in your self.window.rootViewController 'class:

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}


@end

if your rootViewController is [UINavigationController class], command+n add a category of UINavigationController ,like my code below

@implementation UINavigationController (Rotation_For_iOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}


@end

and then ,go to the viewController.m which u want to be landscape or portrait mode,maybe for u is your VideoController !!!!!! add methods below:

#pragma mark
#pragma mark ----- Orientation Control For iOS 6/7 -----

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight||toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

now i set my vc supported for landscape mode, last but not least,make sure your project deployment info select the orientation your want.

Swift 4.1 version

To prevent auto rotation orientation you need to override shouldAutorotate variable

override var shouldAutorotate: Bool {
    return false
}

To present view controller in landscape mode you need to override preferredInterfaceOrientationForPresentation variable

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return .landscapeLeft// or .landscapeRight
}

You need to present view controller to get it work(It doesn't work for pushed view controller)

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationMaskLandscape);
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return (UIInterfaceOrientationMaskLandscape);
}

Try this...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM