iOS8界面旋转方法未被调用

34

willAnimateRotationToInterfaceOrientation:duration:在iOS8中已经被弃用,需要使用viewWillTransitionToSize:withTransitionCoordinator: 替代

然而,在我的视图控制器中,这个方法在iOS8上没有被调用。我需要实现其他什么方法才能让这个回调起作用吗?

我在文档中找不到任何信息。唯一能找到的是它属于新的UIContentContainer协议。然而,即使我明确地将其添加到我的控制器协议中,它仍然无法工作。

有什么想法吗?


我正在将我的viewController作为分段按钮的视图进行加载。在这种情况下,我没有收到viewWillTransitionToSize:withTransitionCoordinator:的调用。你是如何尝试加载viewController的? - Surendra
3个回答

42

viewWillTransitionToSize:withTransitionCoordinator:似乎只在界面实际改变大小时才有效,这意味着我们已经旋转了90度。如果您的布局上有一个只允许横向的掩码,在旋转180度时,界面大小不会改变,因此该方法似乎不会被调用。

我在我的应用程序中通过注册UIDeviceOrientationDidChangeNotification通知来解决这个问题,例如:

(在我的视图控制器的viewWillAppear中):

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

(在我的viewWillDisappear函数中 [记得取消订阅])

[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

我的 deviceOrientationDidChange: 看起来像这样:

- (void)deviceOrientationDidChange:(NSNotification *)notification {
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self willRotateToInterfaceOrientation:orientation duration:1.0];
}

这个解决方法对我也起作用了,而且似乎是目前为止最好的解释。 - tschubotz
1
对于没有状态栏的用户想要进行非标准旋转的情况,这个代码也可以很好地工作:- (void)deviceOrientationDidChange:(NSNotification *)notification { UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; NSLog(@"rotation %li", (long)orientation); } - Ford Davis
这是最好的答案,它起作用了! - Muneeb Rehman

36

按照文档,记得调用super

- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    // ...
}
否则,子视图控制器将无法接收到转发的消息。

虽然这是一个有用的建议,但我可能没有理解它如何回答原始问题...? - yura
谢谢,对于我的情况:我错过了调用addChildViewController。 :D - Linh Nguyen
@yura 如果另一个类接收了消息,但没有通过调用super将其传递,那么你正在工作的类可能不会收到它。 - arlomedia

7

我知道这个问题现在有点过时了,但我认为对于那些可能遇到这个问题的人来说,还可以用另一种方法解决。如果您试图通过addSubview(controller.view)加载属于其他控制器的视图,则还需要将该控制器添加到父控制器中(可能是您要添加到的视图的控制器)。如果您不将控制器添加到父级,则永远不会收到大小更改的更新。后来我们发现了苹果API更改的原因;使用iPad Pro时,您的SizeClass可以在多任务处理能力下无需旋转而更改。这也会调用该方法:

viewWillTransitionToSize(size: CGSize, 
        withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

在父类中,如果你重写了上面的方法,确保你同时调用super,否则你将会找到另一种方式来撞头...

太棒了...解决了我的问题。我没有调用super,这个方法也没有被调用。开始调用super,然后嘿咻...就开始工作了。 - Logicsaurus Rex
如果您尝试使用addSubview(controller.view)加载属于不同控制器的视图,则还需要将该控制器添加到父级(可能是您要添加到的视图的控制器)。如果您不将控制器添加到父级,则永远不会收到大小更改的更新。 - paran
非常感谢!我没有注意到在我的父视图(对于我的大多数应用程序)中没有调用它的超级方法,因此没有任何子视图执行这些方法。 - Edward B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接