UIViewController does not display properly when presented in landscape mode

My application that supports both portrait and landscape orientations. I am presenting a UIViewController modally from a UIViewController located in a UITabBarController using the following code:

self.modalViewController = [[ModalViewController alloc] init]; [self presentViewController:self.modalViewController animated:YES completion:^{ }]; 

ModalViewController is a controller that only the user in Landscape should see. It should be able to rotate the LandscapeRight form in LandscapeLeft. Here's what it looks like:

 @implementation ModalViewController #pragma mark - UIViewController - Orientation - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; } - (BOOL)shouldAutorotate { return YES; } #pragma mark - NSObject - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor greenColor]; } #pragma mark - UIViewController - Status Bar - (BOOL)prefersStatusBarHidden { return YES; } @end 

The controller moves on the left side and completely closes the screen in 95% of cases. But in 5% of cases, it slides from the bottom and covers only the upper half of the screen.

Here's what it looks like when it works fine:

enter image description here

And here is what it looks like when it doesn't work fine:

enter image description here

I created a sample project that can be found here: https://github.com/TitouanVanBelle/Bug

There is a goal of testing the UI to help reproduce the problem, but it rarely works.

Does anyone know why this is happening?

+5
source share
3 answers

Your application supports Portrait, Landscape left, and Landscape right orientation.

The following method is updated in ModalViewController.m -

 - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape|UIInterfaceOrientationMaskPortrait; } 

Your ModelViewController only supports landscape orientation, therefore this problem.

Instead of UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait you can use UIInterfaceOrientationMaskAllButUpsideDown .

EDIT 1

According to your requirement, you can force the current orientation by updating the following code in ModalViewController.m.

 - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor greenColor]; NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; } 
0
source

It should be a comment, but I don't have enough reputation, so answer that.

I think I saw a similar error.

The cause of the problem may be that the orientation changes during the transition in such a way that when viewDidLoad was called, it was still a portrait, but then it was changed to landscape, and the corresponding listener could not answer correctly (perhaps because the state of the transition animation is " in progress "?).

Some ideas on how to fix it:

  • listen for orientation change notifications and explicitly call self.view.setNeedsLayout when the current orientation is landscape.
  • in should autorotate return false if current orientation is portrait

Hope this helps.

0
source

I just tried to implement the same thing. I understood from your question that you want to show the VC model in landscape mode. Here is the solution

1) Add a presentation style to your VC model so that it does not appear on the bottom or half-screen. replace the FirstViewController code with the following

 -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.modalViewController = [[ModalViewController alloc] init]; self.modalViewController.modalPresentationStyle = UIModalPresentationFullScreen; NSAssert([NSThread currentThread] == [NSThread mainThread], @"FAIL"); [self presentViewController:self.modalViewController animated:YES completion:^{}]; }); } 

2) In the VC model, change the ovveriden method supported by InterfaceOrientations to this

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

3) To get a clear idea of ​​rotation, add a view to Model VC to make it clear whether the view rotates or not. Add the following code to Model VC

 -(void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor greenColor]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 100)]; view.backgroundColor = [UIColor redColor]; [self.view addSubview:view]; } 

Now, having done all this, if you try to open the application, it will only open the model VC in landscape mode, which can be turned either left or right, but in sweat mode, it will be disabled.

0
source

Source: https://habr.com/ru/post/1266954/


All Articles