iOS 六及以上控制个别视图旋转案例
iOS 6及以上控制个别视图旋转案例
有这样一个需求:项目的根视图控制器是UITabBarController,有几个tab对应的都是UINavigationController,其中某个UINavigationController的栈中分别有控制器a和控制器b(由控制器a push 进入 控制器b),要求只有控制器b支持旋转。该怎么做呢?大家都知道,在iOS 6及以后,要控制视图的旋转需要在最顶端的控制器中添加下面两个回调方法
// 能否自动旋转 - (BOOL)shouldAutorotate; // 如果能够旋转,返回支持的旋转方向 - (NSInteger)supportedInterfaceOrientations;不同于iOS 6之前只需要在相应的视图控制器中添加下面的回调方法
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;因为项目只要支持iOS 6及以上,所以不需要额外在每个视图控制器中做旋转定制以支持iOS 6以前的系统。那么解决思路就很清晰了,只要在我的最顶层的根视图控制器中,也就是UITabBarController中进行一些判断,如果当前的界面是控制器b的view,那么在shouldAutorotate和supportedInterfaceOrientations中分别返回YES和支持的旋转方向,其余情况一律返回NO和UIInterfaceOrientationMaskPortrait。
下面我们来进行具体操作,首先按需要搭建一个测试工程,工程结构如下图所示
其中,FirstDetailViewController代表的就是需求中的控制b,它是支持除home键在上方向的所有方向。FirstViewController代表控制器a。最方便的解决方法就是添加一个UITabBarController的类别,在类别中添加如下代码
#pragma mark - rotation - (BOOL)shouldAutorotate { UINavigationController *nav = (UINavigationController *)self.selectedViewController; if ([nav isEqual:[self.viewControllers objectAtIndex:0]]) { UIViewController *vc = [nav topViewController]; if ([vc isKindOfClass:[FirstDetailViewController class]]) { return YES; } } return NO; } - (NSInteger)supportedInterfaceOrientations { UINavigationController *nav = (UINavigationController *)self.selectedViewController; if ([nav isEqual:[self.viewControllers objectAtIndex:0]]) { UIViewController *vc = [nav topViewController]; if ([vc isKindOfClass:[FirstDetailViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; } } return UIInterfaceOrientationMaskPortrait; }到这里为止,已经是完成了这个需求。但是这种解决方法并不能应付所有的情况,因为当FirstDetailViewController 在非竖屏的情况下pop的时候,你会发现FirstViewController的旋转方向并没有立马旋转回Portrait方向,而是跟FirstDetailViewController保持一致。索性项目中在FirstDetailViewController pop之前,FirstDetailViewController一定会先返回到Portrait方向,所以就不存在任何问题。跟我的项目相似情况的如优酷手机客户端(视频播放界面代表了视图控制器a),具体亲们可以下载过来看看。
- 1楼gaoyp6小时前
- 在navigation中取当前vc的设置。nnAdd a CustomNavigationControllernnOverride these methods in it:nn-(BOOL)shouldAutorotaten{n return [[self.viewControllers lastObject] shouldAutorotate];n}nn-(NSUInteger)supportedInterfaceOrientationsn{n return [[self.viewControllers lastObject] supportedInterfaceOrientations];n}nn- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentationn{n return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];n}nNow add all orientations in the plistnnenter image description herennIn the view controller add only the required ones:nn-(BOOL)shouldAutorotaten{n return YES;n}nn-(NSUInteger)supportedInterfaceOrientationsn{n return UIInterfaceOrientationMaskPortrait;n}nthese methods override the navigation controller methods