PDA

View Full Version : How to use splitViewController in one TabBarController




mikezang
Aug 11, 2010, 10:31 AM
I have a tab bar controller, and I want to use a split view controller in one tab, I tried to select view controller in inspector, but there is no UISplitViewController, and I tried to inset a UISplitViewController and failed, how can I use UISplitViewController in UITabBarController?



robbieduncan
Aug 11, 2010, 10:45 AM
Basically you can't do what you are trying to do: the split view controller must be the outer most controller (i.e. the one directly within the window). The best you can do is hide the over view when other tabs are selected.

mikezang
Aug 11, 2010, 11:00 AM
The best you can do is hide the over view when other tabs are selected.
What do you mean?

robbieduncan
Aug 11, 2010, 11:07 AM
What do you mean?

I mean exactly what I said. I chose the words carefully after all.

You must have the UISplitViewController as the top-level view controller. It will not allow it's view to be placed inside any other view controllers view. So if you want to use it you must put the tab view controller within the split view controller as either master or detail. Assuming you set the tab controller as master (the larger of the two views) you simply hide the detail view (look at the documentation) for all tabs other than the one you want to show the split on.

mikezang
Aug 11, 2010, 11:22 AM
Yeah, I understood your mean except last one.

I found some samples to talk about use split in tabbar, for example, but my tabbar has others view controller, I just want to add a new tab with splitview, but I am not sure how to keep other tabs what I made in IB, that is my question
http://stackoverflow.com/questions/2475139/uisplitviewcontroller-in-a-tabbar-uitabbarcontroller

http://markivsblog.blogspot.com/2010/04/retrofitting-ipad-uisplitviewcontroller.html

http://stackoverflow.com/questions/2846349/multi-level-navigation-controller-on-left-hand-side-of-uisplitview-with-a-small-t

robbieduncan
Aug 11, 2010, 11:31 AM
I have explained what I would do. This would prevent the problems with iOS 3.2 as discussed in one of those links. I don't use IB so you'll forgive me if I don't try and answer anything to do with that.

newtoiphonesdk
Aug 11, 2010, 01:23 PM
Please let me know if you get something figured out with this. I have been trying to do the same thing. Unfortunately, there is rarely a time when anyone on MacRumors will answer with anything useful. They all seem to like to google whatever your question is and post a link instead of real help. And if you dare ask them for an example they get tight-lipped and think you should take a full course on programming instead of them spending 5 minutes to help. I actually found one guy who went to the trouble of posting about 5 links on how to email from within app in response to a question of how to do that, instead of just posting the UISharedApplication mailto:"@yahoo" code. Very rude folks here.

mikezang
Aug 11, 2010, 05:19 PM
Thanks, guy, you said what I thought!

I have more than 20 years experience in Windows and only half year in Mac.

I never met such forums in past years when I ask something for Windows programming, but here like you said, no experts want to answer your question, they just tell you to google, I am not sure if this is Apple's fashion or they thought they are experts and no paitiant answer anything?!

Anyway, this way is not good for communication....

Anne R. Kist
Aug 11, 2010, 08:00 PM
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];
[tabBarController.view addSubview:splitViewController.view];

mikezang
Aug 12, 2010, 12:34 AM
I got it but not complete, there is no button for popover and..., anyway, this is a little step, I will show your after I got full splitView.

mikezang
Aug 12, 2010, 03:50 AM
I walked one more step, now when I selected row in master view on landscape mode, the detail view will show detail information.
The rest problem is detailView can not act for <UIPopoverControllerDelegate, UISplitViewControllerDelegate> on portrait mode.

Do you have any suggestion?

robbieduncan
Aug 12, 2010, 04:21 AM
I got it but not complete, there is no button for popover

That's not related to the tab-bar thing: you always have to add that yourself. For whatever reason Apple did not make it automatic. You may have some fun doing this on first run as you cannot assume the orientation of the device...

mikezang
Aug 12, 2010, 04:49 AM
I did it in my detail view controller, but I am not sure why the methods don"t be called, this is my next task. do you have any idea?

#pragma mark -
#pragma mark Split view support

- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc {
barButtonItem.title = @"Master List";
NSMutableArray *items = [[toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = 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 {
NSMutableArray *items = [[toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = nil;
}

robbieduncan
Aug 12, 2010, 04:53 AM
What is toolbar? Is it visible on the screen? I don't see it in your screenshots (unless it's the grey bar at the top of the detail: I assumed that was a navigation bar).

mikezang
Aug 12, 2010, 04:58 AM
The gray is toolbar, detailview has no navigation bar.

robbieduncan
Aug 12, 2010, 05:08 AM
OK. Are the methods being called at all (put an NSLog in to check)? If not is the object (the detail view controller I assume) the delegate of the UISplitViewController?

mikezang
Aug 12, 2010, 05:15 AM
I did debug and log, they never be called.

@interface StockDetailController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {
UIPopoverController *popoverController;
UIToolbar *toolbar;

id detailItem;
UILabel *detailDescriptionLabel;
}

robbieduncan
Aug 12, 2010, 05:46 AM
You have declared that the class implements the delegate protocol. This in no way implies that the actual instance of the class is the delegate of any instance of UISplitViewController: you must set the delegate property of the split view controller instance. This is normal: it is like this for every single Cocoa/Cocoa Touch class that has a delegate.

mikezang
Aug 12, 2010, 06:17 AM
Thanks for your suggestion, now I got what I need.

biko01
Sep 28, 2010, 02:30 AM
Mikezang, how did you get this Splitview to show up instead of Navigation or View controller when tab bar item selected? Your image show exactly what I was chasing but no info how it was done?

mikezang
Sep 28, 2010, 03:09 AM
Mikezang, how did you get this Splitview to show up instead of Navigation or View controller when tab bar item selected? Your image show exactly what I was chasing but no info how it was done?
Put makeSplitViewController in applicationDidLaunch method and copy master and detail view controllers from SplitViewController template.
@interface StockManagerAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
UISplitViewController *splitViewController;
UINavigationController *navigationController;
StockMasterController *stockMasterController;
StockDetailController *stockDetailController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet UISplitViewController *splitViewController;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) IBOutlet StockMasterController *stockMasterController;
@property (nonatomic, retain) IBOutlet StockDetailController *stockDetailController;

@end

#import <UIKit/UIKit.h>

@class StockDetailController;

@interface StockMasterController : UITableViewController {
StockDetailController *stockDetailController;
}

@property (nonatomic, retain) IBOutlet StockDetailController *stockDetailController;

@end

-(void) makeSplitViewController {
NSMutableArray *controllers = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
int index = 0;

for (UIViewController *controller in tabBarController.viewControllers) {
if ([controller.tabBarItem.title isEqualToString:@"Stock"]) {
stockDetailController = [[StockDetailController alloc] initWithNibName:@"StockDetailController" bundle:nil];

stockMasterController = [[StockMasterController alloc] initWithStyle:UITableViewStylePlain];
stockMasterController.navigationItem.title = date;
stockMasterController.stockDetailController = stockDetailController;

UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:stockMasterController] autorelease];

splitViewController = [[UISplitViewController alloc] init];
splitViewController.tabBarItem = controller.tabBarItem;
splitViewController.viewControllers = [NSArray arrayWithObjects:nav, stockDetailController, nil];
splitViewController.delegate = stockDetailController;

[controllers replaceObjectAtIndex:index withObject:splitViewController];
}

index++;
}

tabBarController.viewControllers = controllers;
}

biko01
Sep 29, 2010, 09:47 PM
You are a lifesaver! Thanks!:)

thepost
Nov 24, 2010, 06:11 AM
There's no way to do this for the first tab though, to replace the first index of the tab bar controller results in an error:

'NSRangeException', reason: '*** -[NSCFArray removeObjectAtIndex:]: index (0) beyond bounds (0)'

mikezang
Nov 24, 2010, 06:42 AM
There's no way to do this for the first tab though, to replace the first index of the tab bar controller results in an error:

'NSRangeException', reason: '*** -[NSCFArray removeObjectAtIndex:]: index (0) beyond bounds (0)'
Why? in my app, I used it in first tab.

mikezang
Feb 5, 2011, 09:46 AM
Why? in my app, I used it in first tab.
If you use it in first tab with Landscape, you have to add code as below to RootViewController.m
(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.navigationController.toolbar.hidden = YES;
self.navigationController.navigationBar.top = 0;
}
l