iOS UISplitViewController的Popover控制器button在以纵向模式推送新的视图控制器后消失

在我的UISplitViewController应用程序中,我有

  • RootViewController – 左窗格中的视图控制器。
  • DetailViewController – 右侧窗格中的视图控制器。

当点击RootViewController中的一个项目(位于UITableView中)时,将设置新的视图控制器,如下所示:

[detailViewController setViewControllers:[NSArray arrayWithObjects:newViewController, nil] animated:animated];

//detailPane is my DetailViewController

在横向模式下所有的作品都很好。 但是,我不能使UISplitViewController像我想要的纵向模式那样工作,也就是说,当我启动并在portait模式下使用应用程序时,RootViewController的popupbutton不会在我的DetailViewController中正确显示。

当我以纵向模式启动应用程序时,popupbutton会正确显示。 但是在popuppopover中的一个项目并在detailViewController上设置了一个新的视图控制器后,button消失了。 我必须旋转设备到风景然后再回到肖像再次出现button。

我在我的应用程序的AppDelegate中设置我的UISplitViewController的委托,如下所示:

self.splitViewController.delegate = self.detailViewController

这里是我的UISplitViewControllerDelegate实现

 - (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc { NSLog(@"Will hide view controller"); barButtonItem.title = @"Menu"; [self.navigationItem setLeftBarButtonItem:barButtonItem]; self.popoverController = pc; } - (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { NSLog(@"Will show view controller") NSMutableArray *items = [self.navigationItem.leftBarButtonItems mutableCopy]; [items removeAllObjects]; [self.navigationItem setLeftBarButtonItems:items animated:YES]; [items release]; self.popoverController = nil; } 

任何暗示或帮助,不胜感激。 谢谢。

刚刚想出了一个新的解决scheme。

子类UINavigationController并实现UISplitViewControllerDelegate 。 将此类的实例设置为splitViewController的右侧ViewController。 每次你想改变主视图控制器

 NewDetailViewController *newDetailVC = ....// Obtain the new detail VC newDetailVC.navigationItem.leftBarButtonItem = [[[[self.splitViewController.viewControllers objectAtIndex:1]topViewController]navigationItem ]leftBarButtonItem]; //With this you tet a pointer to the button from the first detail VC but from the new detail VC [[self.navigationController.splitViewController.viewControllers objectAtIndex:1]setViewControllers:[NSArray arrayWithObject:newDetailVC]]; //Now you set the new detail VC as the only VC in the array of VCs of the subclassed navigation controller which is the right VC of the split view Controller 

这适用于我,我可以避免定义一个孔协议,并将主设置为委托,这是一个很大的折衷。 希望能帮助到你。

如果你还需要它:

http://developer.apple.com/library/ios/#samplecode/MultipleDetailViews/Introduction/Intro.html

我对我的源(我有类似的设置)来解决它:

我有主viewcontroller(在我的情况下UITableViewController)是UISplitViewController的委托。 在UISplitViewControllers的两个委托方法中(所以这将在你的主视图控制器实现中),你可以在你的类中保存popupviewcontroller和barbuttonitem。 现在,如果你改变你的详细信息viewcontroller,你做:

 self.viewControllers = [NSArray arrayWithObjects:[self.viewControllers objectAtIndex:0], newDetailsViewController, nil]; UIViewController <SubstitutableDetailViewController>*vc = (UIViewController <SubstitutableDetailViewController>*)newDetailsViewController; [vc invalidateRootPopoverButtonItem:_tableViewController.rootPopoverButtonItem]; [_createReportViewController showRootPopoverButtonItem:_tableViewController.rootPopoverButtonItem]; 

我们在哪里

 @protocol SubstitutableDetailViewController - (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem; - (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem; @end 

您的每个detailsViewControllers应坚持的委托。 你会这样实现:

 - (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem { self.navigationItem.leftBarButtonItem = barButtonItem; } - (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem { self.navigationItem.leftBarButtonItem = nil; } 

让我知道这是否有助于你。

我喜欢Nekto的解决scheme,但是却错过了一个关键的问题。

目前还不清楚什么action:select器将导致UISplitViewController在popup窗口中显示MasterViewController。 当我终于明白了这一点时,通过检查debugging器中的BarButtonItem ,我意识到为什么要这么做非常棘手:在iOS的iOS SDK中没有任何地方loggingaction:select器。 哎呀。

尝试这个:

 UIBarButtonItem *showListView = [[UIBarButtonItem alloc] initWithTitle:@"List" style:UIBarButtonItemStyleBordered target:[self splitViewController] action:@selector(toggleMasterVisible:)]; [[detailViewController navigationItem] setLeftBarButtonItem:showListView]; 

你可能想用一个条件来检查窗口是否处于纵向模式,比如if ([self interfaceOrientation] == UIInterfaceOrientationPortrait)

当您设置放置在navigation stack上的新视图控制器时,可能会重置所有导航button。 更改navigation stack后,您可以手动添加适当的button。

例如,你可以从- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc在哪里创build默认的popup窗口控制器button的代码:

 UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"Menu" style:UIBarButtonItemStyleBordered target:self action:@selector(appropriateSelector)]; [self.navigationItem setLeftBarButtonItem:barButtonItem]; self.popoverController = pc;