我有一个返回一个UIViewController YES
中shouldAutorotateToInterfaceOrientation:
为UIDeviceOrientationPortrait
和NO
其他一切.在堆栈顶部的那个视图中,我pushViewController:animated:
用来推动一个新的UIViewController
.新控制器返回YES
任何内容shouldAutorotateToInterfaceOrientation:
.
第一个视图拒绝旋转(如预期的那样).按下第二个视图后,用户可以旋转设备,UI将旋转(也如预期).如果第二个视图处于横向模式并且用户按下后退按钮(调用popViewControllerAnimated:
),则第一个视图将显示为旋转(意外!).
如果用户将设备旋转回纵向,则视图将旋转,然后像以前一样卡在纵向模式中.这可行,但对于用户来说,它们会旋转回来之前很难看.所以我正在寻找一种让这种观点保持纵向模式的方法.
到目前为止我找到的唯一解决方法是使用-[UIDevice setOrientation:]
,它会抛出一个警告(orientation
只读),但是因为实际定义了它.这是一个巨大的黑客,我想要一个真正的解决方案.为了寻找真正的解决方案,我将GDB附加到了Photos应用程序(MobileSlideshow.app)并发现它也使用了-[UIDevice setOrientation:]
.作为一个内部应用程序虽然我猜他们有不同的规则.
有没有正确的方法来实现预期的自转行为?
UIDevice setOrientation的合法替代方法如下:
UIWindow* window = UIApplication.sharedApplication.keyWindow; UIView* view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view];
这会强制当前视图控制器评估其方向,调用shouldAutorotateToInterfaceOrientation并切换远离任何禁止的方向.
例如,以下代码将用于支持所有方向但其父级仅支持格局的视图控制器中:
- (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); }
这是一个老帖子,但因为它还没有解决.我想与其他可能头疼的人分享我的解决方案.
目标:UINavigationController和其堆栈中的大多数viewcontrollers固定在纵向,除了堆栈中的一个viewcontroller允许旋转到纵向和横向.
问题:直观地我通过检查topViewController是否是rotableViewController来设置一个选择性的shouldAutorotateToInterfaceOrientation.但是,在横向模式下从rotableViewController弹回后,导航控制器现在以横向模式显示,尽管不允许.
解决方案:杀手是禁止旋转,viewWillAppear
并在没有动画的情况下呈现和解除modalViewController.
appViewController作为主机viewController添加到窗口中,即RootViewController的rooter;
navigationController被添加到appViewController,委托设置为appViewController;
在AppViewController中
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if (interfaceOrientation == UIInterfaceOrientationPortrait) return YES; return canRotate; }
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated { [viewController viewDidAppear:animated]; canRotate = ([navigationController.topViewController isKindOfClass:[MyRotatable class]]); }
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { [viewController viewWillAppear:animated]; if (![navigationController.topViewController isKindOfClass:[MyRotatable class]]) { canRotate = NO; UIViewController * blanck = [[UIViewController alloc] initWithNibName:nil bundle:nil]; [self presentModalViewController:blanck animated:NO]; [self dismissModalViewControllerAnimated:NO]; [blanck release]; } }