IOS UISplitViewController Popover controller button disappears after pressing a new view controller in portrait mode

In my application UISplitViewController I have

  • RootViewController - view the controller in the left pane.
  • DetailViewController - view the controller in the right pane.

When one item (which is in the UITableView) in the RootViewController is used, the new view controller will be installed as follows:

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

//detailPane is my DetailViewController

Everything works very well in landscape mode. However, I cannot get the UISplitViewController to work the way I want in portrait mode, that is, the Coverage button of the RootViewController does not display properly in my DetailViewController when starting and using the application in portait mode.

When I launch the application in portrait mode, a popover button appears. But after clicking one element in a popover and a new view controller was set to detailViewController, the button disappeared. I have to turn the device to landscape, and then return to the portrait again so that the button appears again.

I set the UISplitViewController delegate to the AppDelegate application as follows:

self.splitViewController.delegate = self.detailViewController

And here is my implementation of 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; } 

Any hints or help is greatly appreciated. Thanks.

+7
source share
4 answers

Just a new solution.

Subclass UINavigationController and implement UISplitViewControllerDelegate . Set an instance of this class as the correct ViewController for splitViewController. Every time you want to change the detail view controller from the wizard

 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 

This works for me, and I can avoid defining a hole protocol and setting the wizard as a delegate, which is a big compromise. Hope this helps.

+4
source

If you still need to:

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

What I did with my source (I had a similar setup for you) to fix this:

I have a master viewcontroller (UITableViewController in my case) is a delegate of UISplitViewController. In the two delegate methods for the UISplitViewControllers (so this will be in your implementation of the master viewcontroller), you would save popupviewcontroller and barbuttonitem in your class. Now, if you change your view to the viewcontroller, you will do:

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

Where

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

The delegate to which each of your detailsControllers elements should follow. You would do the following:

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

Let me know if this helps you.

+3
source

I liked Nekto's solution, but he missed one key problem.

It is not clear which action: selector will cause the UISplitViewController to display the MasterViewController in a popover. When I finally figured it out by BarButtonItem at the BarButtonItem in the debugger, I realized why it's so hard to figure it out: the action: selector action: not registered anywhere in the Apple iOS SDK. Unfortunately.

Try the following:

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

You might want to surround this code with a conditional condition that the window is in portrait mode, for example if ([self interfaceOrientation] == UIInterfaceOrientationPortrait)

+2
source

When you install new view controllers hosted on the navigation stack , probably all navigation buttons are reset. After changing the navigation stack you can manually add the corresponding buttons.

For example, you can select the code from - (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc ;

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

All Articles