willAnimateRotationToInterfaceOrientation 未在 ios6/7 上调用 [英] willAnimateRotationToInterfaceOrientation not called on ios6/7

查看:66
本文介绍了willAnimateRotationToInterfaceOrientation 未在 ios6/7 上调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

在 iOS 7 中强制横向和自动旋转

iOS 6 中的自动旋转有奇怪的行为

在一个类似的主题之后,我发现了这个:

iOS 6 自转问题和帮助

这导致我执行以下操作:

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

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

我已经放置:

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

}

在我的 AppDelegate 中.我在我的应用程序的所有 UIViewController(包括上面提到的 PreloadingViewController)的 SuperViewController(继承术语中的父级)中覆盖了 shouldAutorotatesupportedInterfaceOrientations:

- (BOOL)shouldAutorotate{返回是;}- (NSUInteger)supportedInterfaceOrientations{返回 UIInterfaceOrientationMaskAllButUpsideDown;}

并且在每个子 UIViewController 中,我都覆盖了

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

使用代码以适合纵向和横向方向的方式布局 ui 元素.

最后是我的应用程序在

下的 plist 文件<块引用>

支持的界面方向

包含:

<块引用>

纵向(底部主页按钮)、横向(左侧主页按钮)、横向(右主页按钮)

我想支持的所有方向.

尽管如此,即使我的 rootViewController 上的每个方向更改都会调用 supportedInterfaceOrientationsshouldAutorotate,但永远不会调用 willAnimateRotationToInterfaceOrientation.我什至在 SuperViewController 中重写了 shouldAutomaticallyForwardRotationMethods 以返回 YES,但无济于事.

我在这里做错了什么?有任何想法吗?我什至考虑过旧的 ios5 风格的 xibs 导致了这个问题,但我不认为是这种情况.

提前致谢.

解决方案

由于我的 rootViewController 是唯一一个调用了它的 shouldAutorotatesupportedInterfaceOrientations 方法,我决定注册每个其他视图控制器都会收到任何 UIDeviceOrientationDidChangeNotification 的通知.

[NSNotificationCenter defaultCenter] addObserver:self选择器:@选择器(方向改变:)名称:UIDeviceOrientationDidChangeNotification对象:无];- (void)orientationChanged:(NSNotification *)notification{NSLog(@"方向改变了!");[self layoutForOrientation:[[UIDevice currentDevice]orientation]];}

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

然而,虽然我确实收到了 UIDeviceOrientationDidChangeNotification 通知,但我的视图方向实际上不会改变以匹配当前方向,即如果说新方向,UIInterfaceOrientationLandscapeRight,视图方向将保留在 UIInterfaceOrientationPortrait 中,其子视图将旋转 90 度.这看起来肯定不对.拔了很多头发后,我决定放弃这条路线.

相反,我已将我的 rootViewController 设置为 UINavigationController 并让它在其顶部推送连续的 UIViewController.由于我不想在我的应用程序中显示导航栏,因此我将导航控制器的 navigationBarHidden 属性设置为 YES.通过这种方式,willAnimateRotationToInterfaceOrientation 方法在当前位于 navigationCotroller 控制器堆栈顶部的每个 UIViewController 上被调用,并且其相应的视图和视图控件会针对所需的方向正确旋转.

这是有效的,因为我的大多数视图控制器支持的界面方向与掩码匹配:UIInterfaceOrientationMaskAllButUpsideDown,iPhone 的默认行为.如果我需要支持不同的方向,我将不得不继承 UINavigationController 并覆盖 supportedInterfaceOrientationsshouldAutorotate 以启用导航堆栈的顶部视图控制器所需的方向支持,按照Apple 的示例项目:AlternateViews.

I have an old app, that still lives on iTunes, written in iOS 5. I would like to update it to run on ios 6 and 7. Everything has been fine so far, and I have updated my code to use ARC. However when trying to maintain the same autorotation philosophy I keep hitting a brick wall. I have already checked relative topics within SO like:

Forcing landscape and autorotate in iOS 7,

Autorotate in iOS 6 has strange behaviour

and following a similar topic I have found this:

iOS 6 Autorotation Problems and Help

which lead me to do the following:

I have set the rootViewController within my AppDelegate like so:

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

I have placed:

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

}

within my AppDelegate. I have overriden shouldAutorotate and supportedInterfaceOrientations within the SuperViewController (parent in inheritance terms) of all of my app's UIViewControllers (including PreloadingViewController mentioned above):

- (BOOL)shouldAutorotate{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

and in every child UIViewController, I override

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

with code to layout ui elements in the desirable manner for portrait and landscape orientations.

Finally my app's plist file under

Supported interface orientations

contains:

Portrait (bottom home button), Landscape (left home button), Landscape (right home button)

all the orientations I want to support.

Still, even though supportedInterfaceOrientations and shouldAutorotate are being called for every orientation change on my rootViewController, willAnimateRotationToInterfaceOrientation is never being called. I have even overriden shouldAutomaticallyForwardRotationMethods in my SuperViewController to return YES, but to no avail.

What am I doing wrong here? Any ideas? I have even considered that the old ios5 - style xibs cause the issue but I do not think this is the case.

Thanks in advance.

解决方案

Since my rootViewController was the only one getting its shouldAutorotate and supportedInterfaceOrientations methods called, I decided to register every other view controller to get notified of any UIDeviceOrientationDidChangeNotification.

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

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

Within my layoutForOrientation: method I handled the uiview's controls orientation.

However, although I did receive UIDeviceOrientationDidChangeNotification notifications normally, my view orientation would not actually change to match the current orientation, i.e. if the new orientation was say, UIInterfaceOrientationLandscapeRight, the view orientation would remain in UIInterfaceOrientationPortrait and its children views would get rotated by 90 degrees. This did certainly not look right. After pulling a lot of hair out, I decided to abandon this route.

Instead, I have set my rootViewController to be a UINavigationController and have it push successive UIViewControllers on top of it. Since I did not want a navigation bar visible in my app I have set the navigation controller's navigationBarHidden property set to YES. This way the method willAnimateRotationToInterfaceOrientation is getting called on every UIViewController that is currently at the top of the navigationCotroller's stack of controllers, and its corresponding view and view controls rotate correctly for the desired orientations.

This works because most of my view controllers supported interface orientations match the mask: UIInterfaceOrientationMaskAllButUpsideDown, the default behaviour for iPhone. Should I needed to support different orientations, I would have to subclass the UINavigationController and override supportedInterfaceOrientations and shouldAutorotate to enable the desired orientations support for the navigation stack's top view controller, as per Apple's example project: AlternateViews.

这篇关于willAnimateRotationToInterfaceOrientation 未在 ios6/7 上调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆