[英]ViewController in UINavigationController orientation change
所以我有以下层次结构:
UINavigationController
- > RootViewController( UIViewController
) - > UITableViewController
- > DetailViewController( UIViewController
)
我想将RootViewController上的方向锁定为仅限纵向,但保留其余视图控制器的所有方向。
如果我把它放到子类UINavigationController
:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
然后将所有视图控制器锁定为纵向。
我的问题是,有没有办法只将RootViewController锁定为Portrait,但保留其他视图控制器的所有选项?
检查此处的链接以在iOS 6中修复自动旋转并根据视图设置方向支持: http : //www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
这是你可以做的:
在.m文件中创建一个自定义导航控制器,它是UINavigationController
的子类:
- (BOOL)shouldAutorotate { return self.topViewController.shouldAutorotate; } - (NSUInteger)supportedInterfaceOrientations { return self.topViewController.supportedInterfaceOrientations; }
在你的AppDelegate.h
,
@interface AppDelegate : UIResponder <UIApplicationDelegate> { UINavigationController *navigationController; ViewController *viewController; } @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewController;
在AppDelegate.m
,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // set initial view self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; viewController = [[ViewController alloc] initWithNibName:@"RootViewController" bundle:nil]; navigationController = [[CustomNavigationController alloc] initWithRootViewController:viewController]; // iOS 6 autorotation fix [navigationController setNavigationBarHidden:YES animated:NO]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window setRootViewController:navigationController]; // iOS 6 autorotation fix //[self.window addSubview:navigationController.view]; [self.window makeKeyAndVisible]; return YES; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window // iOS 6 autorotation fix { return UIInterfaceOrientationMaskAll; }
在你的rootViewController中,无论事件推送第二个视图控制器,执行以下操作:
- (IBAction)pushSecondViewController:(id)sender { // push second view controller SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self.navigationController pushViewController:secondViewController animated:YES]; }
在每个视图控制器中,添加
- (BOOL)shouldAutorotate{} - (NSUInteger)supportedInterfaceOrientations{}
对于iOS 6,您可以设置每个视图控制器,无论您需要单独的方向支持。
对于iOS 5及更低版本,您可以设置
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{}
所有学分都归John DiSalvo所有,他在链接中编写了示例应用程序。
希望这可以帮助。
单身
-(void)setOrientationSupport:(BOOL)flag{
flag_orientationSupport_ = flag;
}
-(BOOL)getOrientationSupport{
return flag_orientationSupport_;
}
在appdelegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([singleton getOrientationSupport])
return UIInterfaceOrientationMaskAll;
else
return UIInterfaceOrientationMaskPortrait;
}
在viewwillappear中添加以下代码
对于viewcontroller你想要支持方向
[singleton setOrientationSupport:YES];
到那些你想要禁用方向的控制器
[singleton setOrientationSupport:NO];
把它放在你的导航控制器中:
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
现在,将其添加到根视图控制器:
- (BOOL)shouldAutorotate
{
return NO;
}
应该这样做!
要将定义允许的方向的责任委托给UINavigationController的子视图,可以使用导航控制器的visibleViewController属性使导航控制器“询问”它的子视图以获得其支持的方向。 以下代码应该可以工作(Swift):
分类导航控制器:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { if let visibleView = self.visibleViewController { return visibleView.supportedInterfaceOrientations() } else { return UIInterfaceOrientationMask.All } }
导航控制器的子视图(根视图):
// Restrict to portrait override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.Portrait }
我一直在寻找解决方案几个小时!
所以在各地实施所需的方法之后。 shouldAutorotate
不需要设置为YES
因为它已设置为默认值:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
当需要显示需要与其他视图不同的方向的UIViewController
,我在UIStoryboardSegue
使用此实现创建了一个UIStoryboardSegue
:
#import "Showing.h"
@implementation Showing
- (void)perform{
NSLog(@"Showing");
UIViewController *sourceVC = self.sourceViewController;
UIViewController *presentingVC = self.destinationViewController;
[sourceVC.navigationController presentViewController:presentingVC
animated:YES
completion:nil];
}
@end
在UIStoryboard
内部,我将视图与此segue连接起来( 显示 ):
这很重要,你正在使用
presentViewController:animated:completion:
并不是
pushViewController:animated:
否则将不再确定方向。
[UIViewController attemptRotationToDeviceOrientation];
或者这个在UIViewController
里面的方向应该改变,我也试着在我的自定义UIStoryboardSegues
调用它,然后再presentingViewController
dismissViewController
和dismissViewController
:
NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"];
要么
NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; [[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"];
但他们中没有一个人工作过。 当然最后一个例子不应该是一个选项,因为如果苹果会改变他们api的任何东西,这可能会导致你的应用程序内部出现问题。
我也尝试使用AppDelegate
方法,并在查找实际visibleViewController
的正确UIInterfaceOrientation
之后始终确定此方法内的方向,但是当从一个方向切换到另一个方向时,它有时会发生崩溃。 所以我仍然想知道为什么它变得如此复杂,似乎也没有任何文档可以正确解释。 即使遵循这一部分也没有帮助我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.