强制详细信息视图被隐藏后,UISplitViewController将禁止隐藏ViewController / willShowViewController

时间:2012-02-23 10:52:09

标签: objective-c ipad uisplitviewcontroller

我有一个iPad应用程序,它使用UISplitViewController作为根控制器,我已经设置了委托,我正在为DetailView使用UINavigationController,它似乎正常工作。

当在DetailView部分中显示特定的视图控件时,我希望始终隐藏(在所有旋转中)MasterViewContoller。我可以使用UISplitViewController委托上的shouldHideViewController方法执行此操作。

但是,如果我这样做,那么当我将DetailView部分中的ViewController更改为另一个时,将显示MasterView,但是在委托中都不会调用willHideViewController / willShowViewController。

如果我旋转设备并向后旋转,则会调用它们并按预期工作,但在设备旋转并旋转回原始方向之前不会调用它们。

这会导致在显示MasterView后第一次旋转时不显示弹出按钮。

- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc {

// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button.
barButtonItem.title = @"Survey Sections";
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;

UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];

if ([detailViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController *detailNavController = (UINavigationController *)detailViewController;
    [[detailNavController.viewControllers objectAtIndex:0] showRootPopoverButtonItem:rootPopoverButtonItem];
}

}

- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {

// Nil out references to the popover controller and the popover button, and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];

if ([detailViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController *detailNavController = (UINavigationController *)detailViewController;
    [[detailNavController.viewControllers objectAtIndex:0] invalidateRootPopoverButtonItem:rootPopoverButtonItem];
}

self.popoverController = nil;
self.rootPopoverButtonItem = nil;

}

- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {

UIViewController *detailViewController = [svc.viewControllers objectAtIndex:1];

if ([detailViewController isMemberOfClass:[MySurveysViewController class]]) {
    return YES;
}else {

    if (UIInterfaceOrientationIsLandscape(orientation)) {
        return NO;
    }else {
        return YES;
    }

}

}

1 个答案:

答案 0 :(得分:1)

我遇到了一个非常类似的问题,使用Apple的示例代码和SubstitutableDetailViewController委托结合轮换。

我所做的是在方向为横向时存储BOOL,并使用以下代码在willRotateToInterfaceOrientation上更新它:

isLandscape = UIInterfaceOrientationIsLandscape(self.interfaceOrientation);

viewWillAppear上我检查当前方向是否为横向,如果它与存储的值不匹配,则调用此方法:

-(void)adjustLayoutForOrientation{
    if (isLandscape) {
        [self invalidateRootPopoverButtonItem:  self.navigationController.navigationItem.leftBarButtonItem];
}else{
        LeftViewController *lvc = (LeftViewController *)[self.splitViewController delegate];
        [self showRootPopoverButtonItem:  lvc.rootPopoverButtonItem ];
    }
}

显然我正在使用Apple提供的委托代码,但为了完整起见,这些方法就是这些,并且可以轻松实现:

#pragma mark -
#pragma mark Managing the popover

- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
    // Add the popover button to the left navigation item.
    [self.navigationController.navigationBar.topItem setLeftBarButtonItem:barButtonItem animated:NO];
}


- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
    // Remove the popover button.
    [self.navigationController.navigationBar.topItem setLeftBarButtonItem:nil animated:NO];
}

主视图控制器(左侧)维护对rootPopoverButtonItem的引用,这使其工作。

编辑:请注意,我也在adjustLayoutForOrientationviewDidLoad上调用我的willRotateToInterfaceOrientation方法...更好的方法是注册通知中心,但我不确定背景/隐形视图控制器是否会收到这些通知......