应该在iOS 8中进行动作

laz*_*i74 8 iphone objective-c ios

我在UIViewController shouldAutorotate方法上发现了7.1和8之间的小行为变化.Apple View Controller编程指南指出在执行任何自动旋转之前调用此方法.

但是我注意到,当我只是禁用shouldAutorotate(返回NO)时,该方法在Portrait - > Landscape rotation上调用,但不在下面的Landscape - > Portrait rotation上调用.同样应该始终按照我的理解调用该方法.在iOS 8上运行时会发生这种情况,但在iOS 7.1上则不会.

这似乎与iOS8中调用堆栈中的新方法有关:

[UIWindow shouldAutorotateToInterfaceOrientation:checkForDismissal:isRotationDisabled]

我找不到有关此方法及其行为的任何描述,任何想法,我可以找到有关此内部方法的更多信息

重现这个的简单步骤:

  1. 在Xcode中创建一个新的单视图应用程序项目
  2. 更新您ViewController.m的实施shouldAutorotate

    - (BOOL)shouldAutorotate
    {
        UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
        NSLog(@"%s orientation is %@", __PRETTY_FUNCTION__, [self stringFromDeviceOrientation:orientation]);
        // Disable autorotation of the interface.
        return NO;
    }
    
    - (NSString *) stringFromDeviceOrientation:(UIDeviceOrientation)uido
    {
        NSString *orientation = @"UIDeviceOrientationUnknown";
        switch (uido) {
            case UIDeviceOrientationPortrait:
                orientation = @"Portrait";
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                orientation = @"PortraitUpsideDown";
                break;
            case UIDeviceOrientationLandscapeRight:
                orientation = @"LandscapeRight";
                break;
            case UIDeviceOrientationLandscapeLeft:
                orientation = @"LandscapeLeft";
                break;
            case UIDeviceOrientationFaceDown:
                orientation = @"FaceDown";
                break;
            case UIDeviceOrientationFaceUp:
                orientation = @"FaceUp";
                break; 
                default:
                    break;
            }
            return orientation;
        }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在模拟器上运行iPhone 5s(7.1):shouldAutorotate在切换到横向并返回到纵向时调用

  4. 在模拟器上运行iPhone 5s(8.0)或iPhone 6:shouldAutorotate切换到横向时调用,但切换回纵向时不调用.

bad*_*sel 9

同样的事情发生在我身上.我觉得iOS8中有一个错误,因为我的相同代码在iOS7中运行良好.另外,作为一个用户,我在我使用的应用程序中遇到了很多旋转问题.shouldAutorotate当您旋转到侧面时,在8个调用中,但是当您返回到正常旋转时,不会再次调用.这是除非它实际上对侧面进行了自动旋转,在这种情况下它被称为返回.

所以这是因为你的'shouldAutorotate'总是返回'NO'.我的假设是,出于某种原因,在iOS8中他们(改变这种行为的苹果编码器)决定如果他们在旋转到侧面时得到NO,他们在旋转回到肖像时不需要调用shouldAutorotate.所以它打破了我们期待的行为.

没有人在谈论它或抱怨.Google几乎没有针对此确切方案返回任何结果.我认为这是因为为了要做到这一点你必须要尝试使用"shouldAutorotate"作为一个设备旋转通知,但实际上不使用操作系统的自动旋转功能.例如,我做opengl游戏.所以我只是让我的引擎知道旋转游戏图形.但我不是在转动我的观点.我认为很多人都没有将它用于设备轮换通知.

所以我决定改用设备通知.在我的视图控制器中:

- (void) movingToBackground: (NSNotification *) notification {
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}

- (void) movingToForeground: (NSNotification *) notification {
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
Run Code Online (Sandbox Code Playgroud)

并收到消息:

   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewChanging:) name:UIDeviceOrientationDidChangeNotification object:nil];
Run Code Online (Sandbox Code Playgroud)

方法:

- (void)viewChanging:(NSNotification*)notification
{
   NSLog(@"View is changing");
   previousOrientation = orientation;
   orientation = [[UIDevice currentDevice] orientation];

   if (previousOrientation==orientation && forceReorientation==NO) {
       return;
   }
   ... do stuff ...
Run Code Online (Sandbox Code Playgroud)

然后回到我的视图控制器中,我将所有自动旋转的东西都转为NO.