UISplitviewcontroller not as a rootview controller
Asked Answered
O

5

11

I am building my first iPad application. And one of my requirements is to deal with UISplitviewcontroller and UINavigationController.
our proposed view hierarchy is

(LoginView) ->UINavigationView(LandingView + CollectionView)->UISplitViewcontroller( DetailsView).

Our app supports only landscape mode
I am referring this SO Question( and GILT app as well), as a newbi its hard for me to get it done based on that description.

So my questions are
1) How can I achieve same thing,if somebody can give small code snippets or reference to tutorial
2) As per Apples HIG, UISplitviewcontroller should be rootviewcontroller,what if it not. Will apple reject my app.(apparently GILT group has been approved)
3) I found MGSplitViewController , can I use that one not as root?
Any help would be appreciated. As a newbi i hope my question is genuine

Outdare answered 11/10, 2010 at 19:33 Comment(0)
P
13

If you want to use the out-of the box splitView it must be root; any hokeary-pokery here will either break apples guidelines or manifest very odd behaviour.

The MGSplitViewController is completely custom implementation of a SplitViewController. Its very good if you need that sort of thing, but some of the features are based round the fact that our app will be orientating.

Alternatively you could make your own. I have done this more than once and is easier than it sounds.

(LoginView) ->UINavigationView(LandingView + CollectionView)->UISplitViewcontroller( DetailsView).

Based on an out-of-the-box UISplitView, I would suggest:

  • Make the splitView the root View.

  • Pop (not animated) a full screen Modal as soon as the app starts and allow the user to navigate the loginView, LandingView and collectView in this; i also recommend using a navController here.

  • Once the user is ready to proceed to the splitView, populate the splitView's rootView Controller and DetailViewController with whatever you want then ,animate the Modal out.

Dave does have a point, but i would look at it from the point of view that you are removing the choice of orientation from the user; removing standard choices (like supported orientations) because the designer assumes some configuration is more efficient will only annoy some users.

Permeable answered 12/10, 2010 at 8:31 Comment(4)
Thanks Luke. thats good explanation. one more thought came into my mind is that , what if i use UIsplitviewcontroller and hide rootviewcontroller and use detailview controller as navigation controller?(as i have only landscape mode) is it possible?Outdare
I have not tried this and would take a stab in the dark and say it might give you some unforeseen headaches like resizing the frame of the detail. (in landscape the detailView has an x offset of 350ish) If you really want to do it this way i would butcher the MGSplitViewController into submission. Though don't forget to read the licence first. My original suggestion is definitely most pain free solution.Permeable
As an addon question: even if I make my split view controller root, it will only work when loaded from the main xib. As soon as I put it in a separate xib, associate my view controller - which is inheriting from UISplitViewController - with it, and add it, all I get is a black screen. Putting breakpoints I notice that the inner views of the split controller never get loaded. Seems like the whole xib won't be loaded. But there's no error. Any ideas how to put it into its own xib? Or not possible?Whitt
innerViews? do you mean the rootViewController and detailViewController?Permeable
P
2

I did it by making a method in my detailViewController:

-(void)popHomeScreen:(BOOL)animated//OPENS THE HOMESCREEN IN A MODAL DISPLAY
{

  firstRun=NO;
    //myViewControllerForPopOver init here

    myViewControllerForPopOver.modalPresentationStyle = UIModalPresentationFullScreen;  


        myViewControllerForPopOver.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;//simple anime

    if (animated) [self presentModalViewController:myViewControllerForPopOver animated:YES];
        else [self presentModalViewController:myViewControllerForPopOver animated:NO];  
    }

Then Call it in the detailViewControllers ViewDidAppear method:

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
if(firstRun)[self popHomeScreen:NO];
}

//YOU WILL ALSO NEED TO MAKE 'firstRun=YES' in viewDidLoad
//firstRun is a BOOL

As for the root disappearing (leaving a big black space)..thats a known bug. though i thought for a while that it was caused by ordering an animation while/just before it was going to draw itself.

Also, i found that if i popped a full screen modal over the splitView then popped another form based modal (for example) quickly after it the full screen modal didn't draw properly.

SplitViews are like your mother-in-law, you don't really like them and when you have to use them you have to tip-toe round the landmines.

Permeable answered 17/10, 2010 at 12:19 Comment(1)
- your comment "SplitViews are like your mother-in-law, ..." is just wonderful :-)Lawannalawbreaker
P
2

Try this, it works for me

1) in app delegate's didFinishLaunchingWithOptions make your login view to root view

self.window.rootViewController = self.loginViewController;  

also, init the split view as the template do ( but not add to self.window)

MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:@"MasterViewController_iPad" bundle:nil] autorelease];
UINavigationController *masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];

    DetailViewController *detailViewController = [[[DetailViewController alloc] initWithNibName:@"DetailViewController_iPad" bundle:nil] autorelease];
    UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];

    self.splitViewController = [[[UISplitViewController alloc] init] autorelease];
    self.splitViewController.delegate = detailViewController;
    self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController ,detailNavigationController, nil];

2) add a swap view controller in app's delegate, which swap the root view to split viewcontroller.

-(void)swapToViewControllers:(RootViewControllerType)viewType  
        self.window.rootViewController = self.splitViewController; 

3) invoke the swapToViewControllers in your login view.

Postdiluvian answered 19/6, 2012 at 7:48 Comment(1)
In RootViewControllerType what need to give?Ioyal
D
0

Keep in mind that the HIG strongly encourages you to support all orientations. Unless you have a very, very good reason to support landscape only, you'll probably be rejected.

See page 19 of the HIG: http://developer.apple.com/library/ios/documentation/General/Conceptual/iPadHIG/iPadHIG.pdf

Dysentery answered 11/10, 2010 at 19:46 Comment(2)
Thanks Dave. my app is going to be more of internal use within enterprise. (its not going to be general use.though i have to go thru app store approval process,right) is that good enough?Outdare
Depends on how widely you want it to be distributed. I've developed internal proof-off-concept apps for clients that were deployed on a a handful of devices to show to a few execs. We were completely able ot avoid the app store process this way. If, however, you're developing something that will be distributed throughout the enterprise, you'll want to take a look at this: developer.apple.com/programs/ios/enterprise. It's the Apple enterprise developer program. Don't know much about it, but I think this is probably what you want.Dysentery
D
0

Modified Ryan CY's version with storyboard.

Put this code to login controller.
1. Set storyboard id of UISplitViewController to SplitViewController;
2. Set UISplitViewController delegate and save instance

UISplitViewController* splitController = [self.storyboard instantiateViewControllerWithIdentifier:@"SplitViewController"];
UINavigationController* navigationController = [splitController.viewControllers lastObject];
splitController.delegate = (id)navigationController.topViewController;
3. Change rootViewController after login
self.view.window.rootViewController = splitController;
Darwen answered 1/10, 2013 at 15:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.