iOS 5: 当第一次加载控制器时,willRotateToInterfaceOrientation:duration方法未被调用

8
我已经在我的代码中实现了这种方法,用于知道接口方向的改变会发生什么:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

我依赖该方法来设置视图。在iOS 4或5中,当设备方向改变时,该方法将被调用。

iOS 4还会在控制器首次加载时调用该方法(无论方向是否更改,它都会在开始时正确地调用一次)。

问题是,我注意到在iOS 5中不再这样。该方法只有在设备方向更改时才会被调用,但在控制器最初加载时不会被调用。对我来说这是个问题,因为我依赖它来根据方向设置初始视图布局。

你知道为什么行为会改变吗?应该如何处理?如果在iOS 5上的viewDidLoad中检查方向,然后手动调用willRotate和didRotate方法,这是否是最佳方式?这感觉有点像hack。

谢谢您提供的任何意见。

4个回答

15

由于我时间紧迫,不得不绕过这种奇怪的行为并在viewDidLoad中手动调用方向方法。虽然这有点儿作弊,但到目前为止它工作得很好。

viewDidLoad中,我添加了以下内容:

if ( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0") ) {
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self willRotateToInterfaceOrientation:interfaceOrientation duration:0.2f];
}

我随后将这个代码添加到了一个通用的头文件中:

// iOS Version Checking
#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

我从在SO上这个问题的答案中获取了iOS版本检查定义。


1
我也遇到了同样的问题,一直在苦苦寻找解决方案。最终我找到了一个解决方法,但不幸的是这只适用于iOS 5.0及以上版本:
将以下代码放置在您自定义的UIViewControllerviewDidLoad方法中:
double delayInSeconds = 0.1f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [UIViewController attemptRotationToDeviceOrientation];
});

这将推送旋转更新到下一个运行循环中。 attemptRotationToDeviceOrientation 是一个 iOS 5.0+ 的调用。


1

我也遇到了类似的问题,不过我在tabbarcontroller派生类中覆盖了它才使它正常工作:

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

希望这能有所帮助!

1
自iOS 5及以上版本,您应该通过使用-addChildViewController:构建视图控制器层次结构。此后,子视图控制器将开始再次调用-willRotateToInterfaceOrientation:interfaceOrientation:和其他与界面相关的方法(因为父控制器会通知它们有关UI方向更改的信息)。
请不要使用任何“肮脏”的方法。
有用的文档: Apple关于'addChildViewController:'的文档

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