更新2
在我的UITabBarController子类中,我尝试添加:
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
现在,每当我选择一个标签项时,设备都会完美地旋转到纵向模式。但是,现在我可以在选择(a)时旋转设备,设备将旋转到横向模式。如何阻止设备旋转?
我相信我的tab控制器子类中的这个方法导致了这个:
- (BOOL)shouldAutorotate {
if(self.selectedIndex == 0)
{
return NO;
}
return [self.viewControllers.lastObject shouldAutorotate];
}
如果我回来'否'我在视图控制器中无法旋转,但是当我选择它时,它不会自动旋转为纵向。如果我回来“是”'我可以在视图控制器中旋转,但当我选择它时,它会自动旋转为肖像。
我的应用中有一个自定义标签栏控制器,具有以下层次结构:
UITabBarController
|
UINavigationController
| |
| UIViewController(a)
|
UINavigationController
| |
| UIViewController(b)
|
UINavigationController
|
UIViewController(c)
我希望视图控制器(a)只能在纵向模式下查看,而视图控制器(b)和(c)在所有方向上都可以查看,但是可以颠倒。现在,我可以单独为每个视图控制器执行此操作,但是当我处于横向模式(b)并选择(a)的选项卡项时,我的问题就出现了,然后以横向模式显示a,这看起来不像好。如何确保标签栏(或视图控制器)检查是否可以在当前方向查看要选择的视图控制器?
如果需要,这是我的代码(a)将其自身限制为肖像模式:
- (BOOL) shouldAutorotate
{
return NO;
}
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
更新
我已将此添加到视图控制器(a)中,但我在视图中间看到一个黑色方块,导航栏中的标题不再居中。
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
答案 0 :(得分:5)
由于iOS 7.0 UITabBarController支持通过- (NSUInteger)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController
转发方向。
它很有效,直到您在界面方向切换到另一个选项卡时此特定选项卡不支持。
不幸的是,tabbar控制器在这种情况下不会强制轮换,唯一的方法是使用私有API。
注意:当从仅纵向标签切换回支持任何方向的标签时,我使用attemptRotationToDeviceOrientation
将界面旋转到设备方向。
这是我解决问题的方法:
static const NSInteger kPortraitOnlyTabIndex = 1;
@interface TabBarController : UITabBarController<UITabBarControllerDelegate>
@end
@implementation TabBarController
- (id)initWithCoder:(NSCoder *)aDecoder {
if(self = [super initWithCoder:aDecoder]) {
self.delegate = self;
}
return self;
}
- (NSUInteger)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController {
if(tabBarController.selectedIndex == kPortraitOnlyTabIndex) {
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
[UIViewController attemptRotationToDeviceOrientation];
if([self.viewControllers indexOfObject:viewController] == kPortraitOnlyTabIndex) {
SEL sel = NSSelectorFromString(@"setOrientation:");
if([[UIDevice currentDevice] respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[[UIDevice currentDevice] performSelector:sel withObject:(__bridge id)((void*)UIInterfaceOrientationPortrait)];
#pragma clang diagnostic pop
}
}
}
@end
我将示例应用程序放在https://github.com/pronebird/TabBarOrientationExample
的Github上答案 1 :(得分:2)
我针对这个确切的问题使用过一次解决方法。我们的想法是将UITabBarController
子类化并将其delegate
设置为自身。然后在一个子类中我做了一个跟随“hack”:当选择了仅限肖像的控制器时,我推动并立即解除了一个空模态VC。它迫使iOS以某种方式设置正确的方向。
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
NSInteger currentViewControllerSupportsLandscape = ([viewController supportedInterfaceOrientations] & UIInterfaceOrientationMaskLandscape);
if(UIInterfaceOrientationIsLandscape(currentOrientation) && !currentViewControllerSupportsLandscape) {
//workaround to force rotating to portrait
UIViewController *c = [[UIViewController alloc]init];
[viewController presentViewController:c animated:NO completion:nil];
[viewController dismissViewControllerAnimated:NO completion:nil];
}
}
请注意,它可能取决于某些实现细节,并且可能在将来停止工作。
编辑:您还应该在supportedInterfaceOrientations
子类中实现shouldAutorotate
和UITabBarController
。并且您应该在视图控制器中的YES
中返回-shouldAutorotate
,以保持纵向。否则,在标签栏中选择时,它不会从横向旋转为纵向。
- (NSUInteger) supportedInterfaceOrientations {
return [self.currentViewController supportedInterfaceOrientations];
}
- (BOOL) shouldAutorotate {
return [self.currentViewController shouldAutorotate];
}
- (UIViewController*) currentViewController {
UIViewController* controller = self.selectedViewController;
if([controller isKindOfClass:[UINavigationController class]]) {
controller = [((UINavigationController*)controller).viewControllers objectAtIndex:0];
}
return controller;
}
答案 2 :(得分:0)
它简单,创建UITabBarController的子类,并实现委托方法
- (BOOL)tabBarController:(UITabBarController *)tbController shouldSelectViewController:(UIViewController *)viewController {
//Check for orientation here
if (supported orientation for view controller == [[UIApplication sharedApplication] statusBarOrientation]) {
return YES;
} else {
return NO;
}
}