How to push an UIViewController to UISplitViewController - ios

I want to push an UINavigationController object into an UISplitViewController, but I got the message below:
2014-04-30 02:25:11.215 test_demo[483:70b] Split View Controllers cannot be pushed to a Navigation Controller <UINavigationController: 0x8d34360>.
This is my push method:
- (IBAction)toggleToSplitView:(id)sender {
SplitViewController *splitViewController = [[SplitViewController alloc] init];
[self.navigationController pushViewController:splitViewController animated:YES];
}
In fact, I want to design a login view with a UIViewController, then, I want to push to a UISplitViewController. Anyone who can help me to solve this problem? Any help will be much appreciated.

man. I don't think this is a good idea to push an UIViewController to UISplitViewController. if you must to do it like this. you can use this method:
SplitViewController *splitViewController = [[SplitViewController alloc] init];
[self.view.window setRootViewController:splitViewController];
but, I think this is not a perfect solution. Especially, when you need to add some custom animation during push between different ViewController. thus, maybe you should custom a splitView and added it to an UIViewController. there are many sample code in github for custom UISplitViewController.
https://github.com/Alterplay/APSplitViewController
https://github.com/palaniraja/cUISplitViewController
I hope this help for you.

As the message suggests, you cannot do that.
What you can do is display your SplitViewController first and then present your LoginView from your SplitViewController without animation.

Actually, you're trying to push a UISplitViewController into UINavigationController object. Not vice versa. And it's not allowed. That's what error message says.
UISplitViewController is a specific controller which can be used only as a root view controller in the navigation stack. Also, it can be used only in iPad applications.

-(void)pushView :(UIViewController *)splitViewController{
self.rootViewControllerPre=self.window.rootViewController;
_window.rootViewController=splitViewController;
}
-(void)popView{
_window.rootViewController=_rootViewControllerPre;
}

Related

Can't push viewController because navigationController is nil

I can't perform a transition between viewControllers because navigationController is nil. I have logged navigationController in different parts of the class but it returns nil everywhere. In storyboard the viewController is embedded in a navigationController. I have checked other threads on SO with the same issue, but none of the answer has helped or even really made sense to me.
Can't push because self.navigationController is nil
navigationController is nil,when push the viewcontroller
Why is it nil? And how do I solve this? An error message is also returned:
I have tried both using a segue:
[self.navigationController performSegueWithIdentifier:#"experienceDetails" sender:self];
as well as pushing:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Inspiration" bundle:nil];
ExperienceViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"experience"];
[self.navigationController pushViewController:viewController animated:NO];
Nothing happens using push but an error message is produced:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior
I have looked for solutions on that error too, but there doesn't seem to be a clear and concrete answer to how to solve it. Again, those suggestions I read and tried didn't work.
I'm really at a loss here. Such a simple thing to do but I'm hindered by something I don't even understand.
EDIT
If it helps, I have a tab bar and in one item I have the viewController that is embedded in a navigationController and from there I want to push to another viewController within the same storyboard.
EDIT
I got this to work:
[self showViewController:viewController sender:self];
very likely because it doesn't use navigationController. Its presented as modular though and is not part of the navigation stack, which is not something I want. Just good to know that things would work if navigationController wasn't nil.
I reproduced the described behaviour when segue experienceDetails was created from navigation controller... and here is solution
1) deleted segue experienceDetails form navigation controller
2) created push segue with identifier experienceDetails from included view controller to detail view controller
3) in view controller performed segue from self as below
[self performSegueWithIdentifier:#"experienceDetails" sender:self];

pushViewController not working read much online though

Here is what code I get online, and it does work on previous project that I develop.But in this project, self.navigationController is null when I NSLog it, and guys online talked about add some code in delegate file, but I found nothing in previous project also I am not very clear what code should I add there. Anyone can give me a hand?
UIViewController *next = [[self storyboard] instantiateViewControllerWithIdentifier:#"ViewCollection"];
[self.navigationController pushViewController:next animated:YES];
If UINavigationController is nil, it means that the view controller that you use (which you instantiate from a Storyboard) is not actually embedded within a UINavigationController.
In order to embed it into a UINavigationController, you need to drag and drop a UINavigationController into your Storyboard and then ctrl-drag from the UINavigationController to your custom view controller and set it as the rootViewcontroller of the UINavigationController.
as nburk said: you need a NavigationController with a RootViewController which is your view. and dont forget to set the NavigationController as Initial View Controller. This all is done in the IB.

How to structure an app when using UINavigationController as the window's root view

I'm starting to learn iOS development and am attempting to use UINavigationController as my window's root view. All is working well but I need some advice on how to structure my app. I read the docs and some questions on here too.
Since the navigation controller is managing all my other content view controllers, then all of these view controllers need a way to send messages to the navigation controller. Right? So, I've thought about making a singleton navigation controller that any other view controller can call on to push new view controllers on it. Or, if each view controller has a reference to the navigation controller then they can push/pop easily as well. This is the part I'm not sure about.
Also, for having buttons and actions I have been setting the target as the navigation controller and from there it can handle it correctly and push or pop on it's own. I did subclass UINavigationController for this. And I have my view controllers as references in it. However I ran into an issue where my UITableViewController was handling a selection of a row and I need to push a new view controller on top, but how do I get the reference to the navigation controller?
I hope that makes sense, and any advice on how to structure this would be very appreciated.
Thanks!
I think you're overthinking this. View controllers have a navigationController property built in allowing you to reference the navigation controller. That being said, pushing to a new view controller from within a view controller that is embedded in a navigation controller is as easy as:
UIViewController *myNewViewController = [[UIViewController alloc] init];
[self.navigationController pushViewController:myNewViewController animated:YES];
According to your requirement you need to write like this :-
UIViewController *myNewViewController =
[[[UIViewController alloc]
initWithNibName:#"yourNibName"]
bundle:nil]];
[self.navigationController
pushViewController:myNewViewController
animated:YES];
This will push one controller on the bottom of the stack.

Pushing a view when the rootViewController is not a UINavigationController

Alright, so I've been looking around for an answer to the following question: How to push a certain view controller into view when a push notification arrives from the AppDelegate?
And most answers are that if the rootViewController is a UINavigationController, I have to instantiate a view via my StoryBoard and push it with that root navigation controller.
Here's my situation. Here's how my storyboard is organised:
So as you see my rootViewController doesn't have UINavigationController. So, how do I go about pushing a certain view out of my storyboard?
NOTE: Presenting some separate modal view for push notifications isn't really a great idea. It's my last resort.
I'd like a solution as in the Apple Mail and Message apps.
Alright, I guess I don't give up that easily :) Here's the solution I found to my problem. Since I am presenting my main app views from within a modal view controller, here's what I did:
Since iOS 5 every view controller has a presentedViewController property. Once you know that, it's pretty easy from there.
Here's some specific code from inside AppDelegate.m
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if ([[userInfo objectForKey:#"notificationType"] isEqualToString: #"messageType"]) {
UITabBarController * tabBarController = (UITabBarController *)[self.window.rootViewController presentedViewController];
[tabBarController setSelectedIndex:kChatViewIndex];
// My view controller that I presented modally is a tabBar, your case can be different.
// ... so from here I can reach any navigation controller or any other view from inside my app
}
Now since you've got your view controller, you can use setSelectedIndex: if it's a tabBarController, or push a certain view controller if it's a navigation unit.
Hope this helps anyone with a similar problem.
Cheers!

Moving from one view to another iOS

I'm relatively new to iOS development. I am to move from one viewController to another I use a modal segue transition on button click. This is a game so i want to allow the user to click images to essential move the the app menus.
I have a main page that displays several images, on clicking one i want to be able to move to another view. Currently doing this with a modal segue is causing odd problems with my touchesEnded event where if, for example, i navigate to a page 3 times the touchesEnded event is fired 3 times.
Is there a better way for me to do this or am i just missing thing fundamental?
Thanks
Yes, I think you must make the the navigation controller your root view controller then push views accordingly
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:YOUR_BASE_CONTROLLER]
self.rootViewController = nav;
this is in your app delegate.
Then in your action method
[self.navigationController pushViewController:secondViewController animated:YES]
Im assuming you are using the Storyboard to link VCs using segues.
Modal segues are great for simple transitions but really seem to limit what you can accomplish when they are just linked through SB. Ive found that creating an IBAction that includes the following for a VC segue will allow you to not only control your segues more efficiently but also allow you to have a clearer view of what is actually occurring during the transition.
-(IBAction)goToVc:(id)sender{
//Other code to take place during the segue here
//This will identify the Storyboard in use
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
//This will identify the View Controller to switch to
SecondViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID" ];
[self presentViewController:vc2 animated:YES completion:NULL];
}
Every time you perform a modal segue, you lose the UINavigationController that you were previously using. What you need to do is embed a UINavigationController in the view that you are performing a modal segue to.
Check out a question I answered the other day to help you visualize more clearly what I'm talking about.

Resources