【问题标题】:Force device rotation with +attemptRotationToDeviceOrientation failing强制设备旋转 +attemptRotationToDeviceOrientation 失败
【发布时间】:2013-10-08 03:34:09
【问题描述】:

根据此处的UIViewController 文档,

https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

使用[UIViewController attemptRotationToDeviceOrientation] 会强制系统尝试将界面旋转到新方向。我正在尝试通过以下方式强制界面从纵向旋转到横向:

  • 在尝试旋转之前设置 forceLandscape 标志
  • 致电[UIViewController attemptRotationToDeviceOrientation]
  • 在我的视图控制器中实现-supportedInterfaceOrientations 并检查标志以更改支持的方向,例如

这会强制再次调用-supportedInterfaceOrientations,看起来像

- (NSUInteger)supportedInterfaceOrientations {
    return self.forceLandscape ? UIInterfaceOrientationMaskLandscapeLeft : UIInterfaceOrientationMaskPortrait;
}

即使-supportedInterfaceOrientations 被调用并返回新的方向,界面也不会旋转。我已经确认该项目允许所有方向,并且该视图控制器是窗口的根视图控制器。有没有其他人遇到过这个问题并找到了解决方案?我知道解决这个问题的所有技巧(呈现和解除模式等),但如果可能的话,我想要一个干净的解决方案。我已经在 iOS 6 和 7 上验证了这个问题。

下面是完整的重现代码:

@interface ALTViewController ()
@property (nonatomic, assign) BOOL forceLandscape;
@end

@implementation ALTViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

        self.forceLandscape = NO;
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    [button setTitle:@"button" forState:UIControlStateNormal];
    [button sizeToFit];
    [self.view addSubview:button];
    button.center = self.view.center;
    [button addTarget:self
               action:@selector(buttonPressed:)
     forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonPressed:(id)sender
{
    self.forceLandscape = YES;
    [UIViewController attemptRotationToDeviceOrientation];
}

- (NSUInteger)supportedInterfaceOrientations
{
    return self.forceLandscape ? UIInterfaceOrientationMaskLandscapeLeft : UIInterfaceOrientationMaskPortrait;
}

【问题讨论】:

  • 在您的问题中,您似乎将术语设备与术语接口混合在一起,这使得您很难理解您想要实现的目标。即使设备保持相同的方向,您是否尝试将界面旋转到新的方向?
  • 直到 - 同意:) 为了清楚起见,我只是编辑了这个问题。你是对的,我试图在设备保持纵向时强制界面从纵向到横向。

标签: iphone ios cocoa-touch uiviewcontroller rotation


【解决方案1】:

当且仅当设备本身已旋转时,对 attemptRotationToDeviceOrientation 的调用只会旋转界面的方向。

例如,如果您的视图控制器仅支持纵向,而用户将设备旋转为横向,则不会发生界面旋转。当设备处于横向时,假设您的代码切换了一个允许横向的标志。界面方向会发生什么?什么都没有,因为设备方向已经发生。要使界面方向与设备方向匹配,您需要调用 attemptRotationToDeviceOrientation。

在我自己的代码中,我最近创建了一个自定义的多部分视图动画,如果中间发生界面旋转,它看起来不正确。所以我在简短的动画中关闭了界面旋转。如果用户在动画期间旋转设备,则不会出现界面方向。但是,当重新打开界面方向时,界面不会旋转以匹配设备方向,直到我调用了尝试旋转到设备方向。

【讨论】:

  • 我开始同意你的看法。但是,文档建议我们可以根据应用程序特定条件更改支持的接口:“某些视图控制器可能希望使用特定于应用程序的条件来确定支持哪些界面方向。如果您的视图控制器这样做,当这些条件改变,你的应用应该调用这个类方法。系统会立即尝试旋转到新的方向。"
  • 我在这里问了一个类似的问题stackoverflow.com/questions/20987249/…,我想我的问题是如果它实际上不旋转,那么尝试旋转到设备方向有什么用处?这曾经在 iOS6 之前使用 [UIDevice currentDevice] setOrientation 成为可能。这是一个适用于 iOS7 的 hack,带有编译器警告,但我不会被 App Store 提交接受:objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
  • ` 来这里是说从 XCode 8.3 开始,此调用在模拟器上有时失败,但是当我在设备上尝试时它确实有效。
  • @bilobatum “所以我在简短动画期间关闭了界面旋转”是什么意思?你是怎么做到的?
【解决方案2】:

您可以尝试通过以下方式实现某些目标: setStatusBarOrientation:动画: https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/setStatusBarOrientation:animated:

这为我解决了一个类似的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 2013-08-28
    • 2020-08-02
    • 1970-01-01
    • 2011-01-08
    • 2012-04-07
    相关资源
    最近更新 更多