ViewWillAppear没有使用UISplitViewController调用

时间:2011-10-25 13:55:48

标签: objective-c ios ipad

背景&目标:我有一个基于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;
}
viewWillAppearDetailViewController.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消息以跟踪shouldAutorotateToInterfaceOrientationviewWillAppearViewDidLoad

3 个答案:

答案 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));
}

现在将HostManagerViewControllerDetailViewController中的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);
}