我有一个 UIViewController,它在 shouldAutorotateToInterfaceOrientation:
中为 UIDeviceOrientationPortrait
返回 YES
,为其他所有内容返回 NO
。将该 View 置于堆栈顶部后,我使用 pushViewController:animated:
推送新的 UIViewController
。对于 shouldAutorotateToInterfaceOrientation:
中的任何内容,新 Controller 都会返回 YES
。
第一个 View 拒绝旋转(如预期)。推送第二个 View 后,用户可以旋转设备,并且 UI 将旋转(也如预期)。如果第二个 View 处于横向模式并且用户按下后退按钮(调用 popViewControllerAnimated:
),第一个 View 将出现旋转(意外!)。
如果用户将设备旋转回纵向, View 将旋转,然后像以前一样停留在纵向模式。这可行,但对于用户来说很难看,直到他们旋转回来。因此,我正在寻找一种方法使该 View 保持纵向模式。
到目前为止,我发现的唯一解决方法是使用 -[UIDevice setOrientation:]
,它会抛出警告(orientation
是只读的),但可以使用实际上是定义的。这是一个巨大的黑客攻击,我想要一个真正的解决方案。为了寻找真正的解决方案,我将 GDB 连接到照片应用程序 (MobileSlideshow.app),并发现它也使用 -[UIDevice setOrientation:]
。作为一个内部应用程序,尽管我猜他们有不同的规则。
是否有正确的方法来实现预期的自动旋转行为?
最佳答案
UIDevice setOrientation 的合法替代方法如下:
UIWindow* window = UIApplication.sharedApplication.keyWindow;
UIView* view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
这会强制当前 View Controller 评估其方向,调用 shouldAutorotateToInterfaceOrientation 并远离任何禁止的方向。
例如以下代码将用在支持所有方向但其父级仅支持横向的 View Controller 中:
- (void)popBack
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (IBAction)backPressed:(id)sender
{
portraitOrientationPermitted = NO;
// Force the framework to re-evaluate the interface orientation.
UIWindow* window = UIApplication.sharedApplication.keyWindow;
UIView* view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
[self performSelector:@selector(popBack) withObject:nil afterDelay:0.8];
portraitOrientationPermitted = YES;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return portraitOrientationPermitted ||
UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
关于iphone - UINavigationController 和自动旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/970482/