在横向模式下呈现时,UIViewController无法正确显示

时间:2017-04-20 04:33:32

标签: ios objective-c uiviewcontroller

我的应用程序支持纵向和横向方向。我使用以下代码从位于UITabBarController中的UIViewController以模态方式呈现UIViewController:

self.modalViewController = [[ModalViewController alloc] init];

[self presentViewController:self.modalViewController animated:YES completion:^{

}];

ModalViewController是一个控制器,只能由Landscape中的用户看到。它应该能够从LandscapeRight旋转到LandscapeLeft。这就是它的样子:

@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

控制器从左侧向上滑动,并在95%的时间内完全覆盖屏幕。但有5%的时间,它从底部向上滑动,仅覆盖屏幕的上半部分。

以下是它工作正常时的样子:

enter image description here

以下是它无法正常工作的样子:

enter image description here

我创建了一个示例项目,可在此处找到:https://github.com/TitouanVanBelle/Bug

有一个UI测试目标可以帮助重现该问题,但它很少有效。

有谁知道为什么会这样?

3 个答案:

答案 0 :(得分:0)

您的应用程序支持纵向,横向左侧和横向右侧方向。

在ModalViewController.m中更新以下方法 -

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

你的ModelViewController只支持横向,因此就是这个问题。

您可以使用 UIInterfaceOrientationMaskAllButUpsideDown 代替 UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait

编辑1

根据您的要求,您可以通过更新ModalViewController.m中的以下代码来强制旋转当前方向。

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor greenColor];

    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

答案 1 :(得分:0)

这应该是一个评论,但我没有足够的声誉,所以回答它。

我想我已经看到了类似的错误。

问题的原因可能是在转换期间方向发生变化,以至于当调用viewDidLoad时它仍然是纵向,但随后更改为横向并且相应的侦听器无法正确响应(可能是因为转换动画状态为&# 34;正在进行"?)。

关于如何解决问题的一些想法:

  • 收听方向更改通知,并在当前方向为横向时显式调用self.view.setNeedsLayout
  • in should autorotate如果当前方向是纵向,则返回false

希望它有所帮助。

答案 2 :(得分:0)

我只是试图实现同样的目的。我从你的问题中了解到,你只想在横向模式下展示模型VC。这是解决方案

1)向模型VC添加演示样式,使其不会从底部或半屏幕显示。将FirstViewController代码替换为以下

-(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)在模型VC中,将ovveriden方法supportedInterfaceOrientations更改为此

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

3)要获得清晰的旋转概念,请在模型VC上添加视图,以便清楚视图是否旋转。在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];
}

现在完成所有这些操作后,如果您尝试打开应用程序,它将仅以横向模式打开Model VC,可以向左或向右横向旋转,但将禁用potrait模式。