ViewWillAppear没有被UISplitViewController调用
背景和目标:我有一个UISplitViewController基于iPad的应用程序 – 直到现在它支持4个方向,但现在我想locking它只有风景。 我改变左视图控制器的shouldAutorotateToInterfaceOrientation
只支持横向模式,但是这停止了它的viewWillAppear
被调用。
详细信息:我的iPad的视图控制器组织如下:
window `-- splitVC (UISplitViewController) `-- rootNav (UINavigationController) `-- hvc (HostManagerViewController, derived from UIViewController) `-- detailViewController (DetailViewController, derived from UIViewController)
这是在App Delegate中实现的,如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { HostManagerViewController *hvc = [[[HostManagerViewController alloc] initWithNibName:nil bundle:nil] autorelease]; self.detailViewController = [[[DetailViewController alloc] initWithNibName:nil bundle:nil] autorelease]; UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:hvc] autorelease]; UISplitViewController *splitVC= [[[UISplitViewController alloc] init] autorelease]; [splitVC setViewControllers:[NSArray arrayWithObjects:rootNav, detailViewController, nil]]; splitVC.delegate = detailViewController; [window addSubview:splitVC.view]; [window setRootViewController:splitVC]; return YES; }
当DetailViewController.m
和HostManagerViewController.m
都包含时, viewWillAppear
被调用
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } Console output: Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 3 Hostmanager: Viewdidload Should rotate called to hostmanager with 1 Hostmanager: viewwillappear
但是当我更改HostManagerViewController
的代码
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (UIInterfaceOrientationIsLandscape(interfaceOrientation)); }
那么HostManagerViewController的“viewWillAppear”不会被调用。 控制台输出
Should rotate called to hostmanager with 1 (1 is the numeric value of interfaceOrientation) Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 3 Should rotate called to hostmanager with 3 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 3 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 3 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 1 Should rotate called to hostmanager with 3 Hostmanager: Viewdidload Should rotate called to hostmanager with 1
Info.plist中只支持横向模式
编辑:插入NSLog消息跟踪ViewDidLoad
, viewWillAppear
和ViewDidLoad
我问你使用的是什么版本的iOS,因为我试图创build一个简单的问题复制,发现4.3和5.0之间的行为不同。 它实际上确实在5.0中进行了所有正确的调用。 我相信这只是与UISplitviewController的一个错误。 Splitview控制器相当麻烦。 aopsfan的回答没有解决问题(我已经证实了这一点)。 我build议子类化uisplitviewcontroller,并重写splitview控制器的viewwillappear,viewdid像这样出现:
#import "testSplitViewController.h" @implementation testSplitViewController -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSString *reqSysVer = @"5.0"; NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; if ([currSysVer compare:reqSysVer options:NSNumericSearch] == NSOrderedAscending) [[[self viewControllers] objectAtIndex:0] viewWillAppear:animated]; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSString *reqSysVer = @"5.0"; NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; if ([currSysVer compare:reqSysVer options:NSNumericSearch] == NSOrderedAscending) [[[self viewControllers] objectAtIndex:0] viewDidAppear:animated]; } @end
您必须检查版本号,以便您不要使viewDidAppear调用两次。
或者如果可以的话,只需要5.0或更高,因为这个bug似乎是固定的。
基本上,因为一个UISplitViewController
有两个部分,所以你需要一个通用的UISplitViewController
实现。 我认为,单独处理视图控制器的旋转可能会导致一些奇怪的副作用 – 尽pipe请注意,我无法复制viewWillAppear
问题,所以这个解决scheme真的是一个猜测。
我会build议做一个UISplitViewController
的死简单的子类。 将其命名为“SplitViewController”,并将其命名为.m
文件,删除除了shouldAutorotate之外的所有内容,如下所示:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (UIInterfaceOrientationIsLandscape(interfaceOrientation)); }
现在在HostManagerViewController
和DetailViewController
HostManagerViewController
您的HostManagerViewController
代码改回到:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; }
现在,在您的应用程序委托中,使用此类而不是UISplitViewController
。 这应该(可能)解决您的问题。
您将UISplitViewControler的委托设置为detailViewController
splitVC.delegate = detailViewController;
我认为阻止旋转的最佳位置将在DetailViewController中,而不是在HostManagerViewController中。 我会更改HostManagerViewController中的 – shouldAutorotateToInterfaceOrientation返回allways是,并在DetailViewController我会添加:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (UIInterfaceOrientationIsLandscape == interfaceOrientation); }