在ios6 / 7上没有调用willAnimateRotationToInterfaceOrientation

时间:2013-12-06 13:52:47

标签: ios iphone objective-c uiviewcontroller autorotate

我有一个旧的应用程序,它仍然存在于iTunes上,用iOS 5编写。我想将其更新为在ios 6和7上运行。到目前为止一切都很好,我已经更新了我的代码以使用ARC 。然而,当我试图保持相同的自转哲学时,我一直在打砖墙。我已经检查了SO中的相关主题,如:

Forcing landscape and autorotate in iOS 7

Autorotate in iOS 6 has strange behaviour

并按照类似的主题发现了这个:

iOS 6 Autorotation Problems and Help

引导我做以下事情:

我已经在我的AppDelegate中设置了rootViewController,如下所示:

self.preloadingViewController = [[PreloadingViewController alloc] initWithNibName:@"PreloadingViewController" bundle:nil];
self.window.rootViewController = self.preloadingViewController;

我已经放置了:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAllButUpsideDown;

}

在我的AppDelegate中。我在我的所有应用程序的UIViewControllers(包括上面提到的PreloadingViewController)的SuperViewController(继承术语中的父对象)中覆盖了shouldAutorotatesupportedInterfaceOrientations

- (BOOL)shouldAutorotate{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

并且在每个子UIViewController中,我重写

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

使用代码以理想的方式为纵向和横向方向布置ui元素。

最后我的应用程序的plist文件在

  

支持的界面方向

包含:

  

人像(底部主页按钮),风景(左主页按钮),风景   (右主页按钮)

我想支持的所有方向。

尽管我的rootViewController上的每个方向更改都调用supportedInterfaceOrientationsshouldAutorotate,但永远不会调用willAnimateRotationToInterfaceOrientation。我甚至在我的SuperViewController中覆盖shouldAutomaticallyForwardRotationMethods以返回YES,但无济于事。

我在这里做错了什么?有任何想法吗?我甚至认为旧的ios5风格的xib引起了这个问题,但我不认为是这种情况。

提前致谢。

3 个答案:

答案 0 :(得分:3)

在iOS 6中,调用willAnimateRotationToInterfaceOrientation的方式发生了变化。

使用:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Something
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    // Something
}

rootController

编辑:

New main.m

#import <UIKit/UIKit.h>
#import "yourAppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([yourAppDelegate class]));
    }
}

答案 1 :(得分:2)

由于我的rootViewController是唯一一个调用其shouldAutorotatesupportedInterfaceOrientations方法的人,因此我决定注册其他所有视图控制器以获得任何UIDeviceOrientationDidChangeNotification的通知。

[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];

- (void)orientationChanged:(NSNotification *)notification
{
    NSLog(@"Orientation changed!");
    [self layoutForOrientation:[[UIDevice currentDevice] orientation]];
}

在我的layoutForOrientation:方法中,我处理了uiview的控件方向。

但是,虽然我确实收到了UIDeviceOrientationDidChangeNotification次通知,但我的视图方向实际上并没有改变以匹配当前方向,即如果新方向是UIInterfaceOrientationLandscapeRight,则视图方向将保留在UIInterfaceOrientationPortrait及其子视图将旋转90度。这看起来肯定不正确。拉了很多头发后,我决定放弃这条路线。

相反,我已将我的rootViewController设置为UINavigationController并让它在其上推送连续的UIViewControllers。由于我不想在我的应用程序中看到导航栏,因此我将导航控制器的navigationBarHidden属性设置为YES。这样,方法willAnimateRotationToInterfaceOrientation就会在当前位于navigationCotroller控制器堆栈顶部的每个UIViewController上调用,并且其相应的视图和视图控件可以正确旋转以获得所需的方向。

这是有效的,因为我的大多数视图控制器支持的界面方向与掩码匹配:UIInterfaceOrientationMaskAllButUpsideDown,这是iPhone的默认行为。我是否需要支持不同的方向,我必须继承UINavigationController并覆盖supportedInterfaceOrientationsshouldAutorotate,以便为导航堆栈的顶视图控制器启用所需的方向支持,如Apple的示例项目所示:{{ 3}}

答案 2 :(得分:0)

实施此方法,根据需要返回YES。

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation