UISplitViewController delegate methods not called
Asked Answered
C

3

9

I am using a UISplitViewController inside a UITabBarController with a plain UIViewController in the master pane of the split view and a UINavigationController in the detail pane, which itself contains a vanilla UIViewController.

I am aware that Apple advise to use split views at the root level only, however I have seen other applications (eg, Amazon- 'Wish List' tab) that use split views in tabs so I'm sure it's possible.

My problem is that the delegate methods of the split view, ie. those in UISplitViewControllerDelegate do not get called, which prevents me from creating my pop-over menu when switching into Portrait mode.

The methods in question are the following -

// Called when a button should be added to a toolbar for a hidden view controller
- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc;

// Called when the view is shown again in the split view, invalidating the button and popover controller
- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem;

// Called when the view controller is shown in a popover so the delegate can take action like hiding other popovers.
- (void)splitViewController: (UISplitViewController*)svc popoverController: (UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController;

The UISplitViewController does receive the rotation notifications.

I can get the willShowViewController method to be called if I force the status bar orientation to landscape right (or left) at the beginning of the app launch, using

 [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];

However, the willHideViewController doesn't get called. And I don't want to force the app to start in landscape. If I do the same thing but force it to portrait, I don't receive the callbacks.

I don't understand why the split view controller is not calling it's delegate methods when it is otherwise behaving correctly. These methods should be called from its method-

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

internally, and when I breakpoint inside this, I can check that the delegate is set and that it is still alive.

Been stuck on this all day! Everything else is working great and I'm very pleased that the splitview / tabbar / navbar combination is working well. I just need these notifications.

Should I perhaps just call them manually when I rotate? Seems very wrong when the `UISplitViewController' should be doing this.

Coerce answered 10/1, 2011 at 17:34 Comment(0)
C
6

Solved, it has to be at either root level or a direct subview of a tabBar which also must be at root level. Annoying!

Coerce answered 18/1, 2011 at 17:29 Comment(6)
Hello, would you mind to elaborate your solution a little bit further? I have kind of the same problem right now. I got 1 tabcontroller wich has a splitview in 3 tabs. I added the detailview in each splitview to an own subclassed navigationcontroller wich delegates the splitview. This is working flawless for the currently visible tab but not for the others. So when i rotate my view and change the tab it looks all messed up, until i rotate it. Again, then only for the visible view.Swoop
hmm sorry I'm not sure.. I'm sure I've seen a post on here somewhere that indicated that changing between splitview tabs and rotating caused problems, and that the splitviwe should always be at window level- not even under a tab controller. Which is backed up by the docs I guess. I'm actually taking the route of building my own SplitView from scratch as I require horizontal splitsCoerce
Instead of trying from scratch, try this - mattgemmell.com/2010/07/31/mgsplitviewcontroller-for-ipadZoo
not an option due to the license. I ended up making my own, was easy and works greatCoerce
hey Sam can you share the sample code, how did you solve this, I'm kinna struggling with thisSleeper
To elaborate @Sam's answer: you need to setup the UISplitViewController and implement UISplitViewControllerDelegate in your UITabBarController or a similar root level view controller. It won't work if you implement the delegate in any other VC. This is the kind of bs that makes me very annoyed at Apple.Delivery
D
3

First, try to see if you are setting the correct delegates. e.g., lets say you created three controllers,

UISplitViewController* splitView;
UIViewController* masterView;
UIViewController* detailView;

You implemented the delegate protocol at the detail view, so that when orientation changes, detail view should be able to put a button in the toolbar.

Now in order for splitView to call this function from delegate, you need to set the delegate itself.

So somewhere, if you are missing the following call,

splitView.delegate = detailView;

detailView's will never get notified of the orientation changes etc. At least this is where I was stuck.

Dad answered 6/1, 2012 at 15:43 Comment(0)
R
2

I like the following method of sending a message from the master UIViewController to the detail UIViewController. Somewhere inside the master's implementation:

id detailViewController = [[self.splitViewController viewControllers] lastObject];
[detailViewController setSomeProperty:…];

This is from Paul Hegarty's Fall 2011 Stanford iTunesU iPad and iPhone Application Development course.

Rendition answered 9/12, 2012 at 6:18 Comment(1)
I like your idea very much because it is a thought outside the box.Dewittdewlap

© 2022 - 2024 — McMap. All rights reserved.