【问题标题】:UIViewController not showing properly when presented in landscape modeUIViewController 在横向模式下显示不正确
【发布时间】:2017-09-16 12:58:39
【问题描述】:

我的应用程序同时支持纵向和横向方向。我正在使用以下代码从位于 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% 的情况下,它会从底部向上滑动,只覆盖屏幕的上半部分。

这是它正常工作时的样子:

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

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

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

有人知道为什么会这样吗?

【问题讨论】:

  • 感谢发帖,也在寻求解决方案

标签: ios objective-c uiviewcontroller


【解决方案1】:

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

在 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"];
}

【讨论】:

  • 但是用户将能够以横向和纵向显示 ModalViewController,我不希望这样。我只希望他们在横向模式下看到它
  • 啊……你的问题并不清楚。给我一些时间我会更新我的答案
  • 正如评论stackoverflow.com/questions/26357162/… 中提到的那样,使用此 API 是不安全的,并且可能会在任何 iOS 版本中中断。同样在这里,模态 vc 从底部而不是从左侧向上滑动,整个应用程序旋转,这不是我想要的。
【解决方案2】:

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

我想我见过类似的错误。

问题的原因可能是在转换过程中方向发生了变化,当调用 viewDidLoad 时它仍然是纵向的,但随后更改为横向并且相应的侦听器未能正确响应(可能是因为转换动画状态为“in进展”?)。

关于如何修复它的一些想法:

  • 在当前方向为横向时收听方向更改通知并显式调用 self.view.setNeedsLayout
  • 如果当前方向是纵向,则应该自动旋转返回 false

希望对你有帮助。

【讨论】:

  • 我已经尝试在 shouldAutorotate 中返回 NO,但它不能解决问题。我将尝试第一个解决方案。谢谢
  • 即使在调用 [self.view setNeedsLayout] 时也能重现该问题;
【解决方案3】:

我只是尝试实现相同的功能。我从您的问题中了解到,您只想以横向模式显示模型 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 上添加一个视图,以便清楚视图是否正在旋转。在模型 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,该模型可以横向向左或向右旋转,但纵向模式将被禁用。

【讨论】:

  • 使用此解决方案仍然可以重现该问题。
猜你喜欢
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 2016-11-29
  • 1970-01-01
  • 2018-01-18
相关资源
最近更新 更多