背景&目标:我有一个基于UISplitViewController的iPad应用程序 - 到现在它支持4个方向但现在我想将其锁定为仅景观。
我更改了左视图控制器的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;
}
当viewWillAppear
和DetailViewController.m
都包含时,会调用{p> HostManagerViewController.m
- (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消息以跟踪shouldAutorotateToInterfaceOrientation
,viewWillAppear
和ViewDidLoad
答案 0 :(得分:8)
我问你正在使用什么iOS版本因为我试图创建一个简单的问题再现,发现4.3和5.0之间的行为不同。它实际上确实在5.0中进行了所有正确的调用。我相信这只是UISplitviewController的一个错误。 Splitview控制器非常多。 aopsfan的答案并没有解决问题(我已经证实了这一点)。我建议继承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或更高版本,因为错误似乎已得到解决。
答案 1 :(得分:3)
基本上,由于UISplitViewController
有两个部分,因此需要一个通用的shouldAutorotate实现。我认为单独处理视图控制器的旋转可能会导致一些奇怪的副作用 - 但请注意我无法复制您的viewWillAppear
问题,所以这个解决方案真的是猜测。
我建议制作UISplitViewController
的死简单子类。将其命名为“SplitViewController”,并在其.m
文件中删除除shouldAutorotate之外的所有内容,如下所示:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
现在将HostManagerViewController
和DetailViewController
中的shouldAutorotate代码更改回:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
现在,在您的app delegate中,使用此类而不是UISplitViewController
。这应该(可能)解决您的问题。
答案 2 :(得分:0)
您将UISplitViewControler的委托设置为detailViewController
splitVC.delegate = detailViewController;
我认为阻止旋转的最佳位置将在DetailViewController中,而不是在HostManagerViewController中。我会改变HostManagerViewController中的 - shouldAutorotateToInterfaceOrientation以返回始终是YES并且在DetailViewController中我会添加:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (UIInterfaceOrientationIsLandscape == interfaceOrientation);
}