Navigation Controller. Navigation between multiple view controllers - objective-c

![This is My view controller connection looks][1]
http://i58.tinypic.com/2mepfv4.png
![I have to go from view controller A to VC-B through programatically, Because it should satisfy login authentication based on device ID. Let me Explain Clearly. When user installs my app he should set up his email and verify.After verification He should move to VC-B.After moving VC-B, Viewcontroller-A should not open again when he opens app again. Something like kill View controller-A, and load VC-B whenever he opens app.
Question1- How to kill View controller-A completly.
Second thing i do not want to show navigation bar On View controller-A, But on View VC-B,VC-C and VC-D so on. i want to show navigation bar because user should be able to move back and forth.That's the reason i added navigation controller before VC-B again.
If i'm not able to show Navigation bar on VC-B until i enable show navigation bar on Navigation controller before View Controller A.
Question2-How to enable Navigation bar on VC-B but not on Viewcontroller-A.
][1]
This is the code how am i moving from View controller A to VC-B.
if (alertView.tag == 99) {
if(buttonIndex == 0){
VC-B *vcb =
[self.storyboard instantiateViewControllerWithIdentifier:#"VC-B"];
[self.navigationController pushViewController:vcb animated:YES];
}
}
Help me to point Right direction.

You do not necessarily need to kill the A view controller, I do not think this is a good idea.
You can solve the issue by setting the info in NSUserDefaults when the user is successfully verified. Then navigate to the B view controller.
In the method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
always check if that verified flag was set in NSUserDefaults, and if YES - set the rootViewController of the navigation controller to the B view controller, otherwise to the A view controller.
To hide/unhide the Nav Bar, you can do it from any view controller (assuming they belong to a navigation controller), using this code:
self.navigationController.navigationBar.hidden = YES; // or NO
This code can be written in the view controller classes, inside viewDidLoad, viewWillAppear:, viewDidAppear:, or anywhere you need.
There are also some methods if you want a nice animation for hiding/unhiding.

Related

how to push to another viewcontroller (detail view) using segue on a uisplitviewcontroller

I'm starting to work on an ipad application that would require activity (or functions) on the detail view and would push (or transfer) to another view controller depending on the button tapped.
Trying to figure out if segue is what I'm supposed to be using with this.
My storyboard looks like this:
SplitViewController -> navigationcontroller(master view) / login
(detail view) -> dashboard (will be transferred on successful login
But whenver I tap the button and successfully login it would give me this error:
Push segues can only be used when the source controller is managed by
an instance of UINavigationController.'
Thoughts?
EDIT: Code that pushes to the next viewcontroller
- (IBAction)btnSubmit:(id)sender {
User *user = [[User alloc] init];
user.email = self.txtEmail.text;
user.rawPassword = self.txtPassword.text;
if(user.isValid){
[self performSegueWithIdentifier:#"LoginSuccess" sender:self];
}
}
The error is telling you that you are using the option push without embedding a navigation controller. If you don't want to use navigation controller just click on the segue connection in storyboard and change it to modal and it will move the views without error.

Pushing a navigation controller is not supported- performing segues

I created a new navigation controller in my storyboard (not programmatically!) and set it to be "Root View Controller" to a regular UIViewController and added a button in it which says- forward to the next view controller (this second view controller is a view controller which I want that will have a back button to link to the initial view controller).
Now, whenever I try to link the button to the next view controller- "Pushing a navigation controller is not supported".
Help me please, and thanks
EDIT:
I accidentally subclassed UINavigationController, and not UIViewController in my class.
Thank you anyway.
I've tried this and have no problems, its all done in IB with no additional code required ...
Start a new project, "Single View Application" using story boards
Select storyboard and delete the views its produced.
Drag on a new Navigation Controller (it will bring a table view with it)
Delete the table and the table view controller, so you are just left with the Navigation Controller
Drag on a normal view controller
Right Click and drag from the Navigation controller to the new View and choose "Relationship - Root View Controller"
Drag a "Bar Button Item" on to the Navbar which should be visible on the top of your ViewController, you can rename this Forward if you wish.
Now drag on another view controller which is the one your "Forward" button will push in to view.
Right Click and drag from the bar button to the 2nd View Controller, and choose "Push"
Run the project and you will get a Single view with a Navbar and your button, clicking your button will Push the other view and give you a Back Button to return to the first View Controller. I'll try and post a picture of my storyboard if it helps.
Plasma
I had the same trouble. I wanted to have a navigation controller on each storyboard, so that each could run independently, be individually debugged, and so that the look would be right with the navigation bar.
Using other approaches, I found the UINavigationController would be retained from the original storyboard -- which I didn't want -- or I'd get errors.
Using the AppDelegate in your view controller to set the rootViewController worked for me (borrowing segue naming conventions from Segue to another storyboard?):
- (void)showStartupNavigationController {
NSLog(#"-- Loading storyboard --");
//Get the storyboard from the main bundle.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Startup" bundle:nil];
//The navigation controller, not the view controller, is marked as the initial scene.
UINavigationController *theInitialViewController = [storyBoard instantiateInitialViewController];
NSLog(#"-- Loading storyboard -- Nav controller: %#", theInitialViewController);
//Remove the current navigation controller.
[self.navigationController.view removeFromSuperview];
UIWindow *window = [(AppDelegate *)[[UIApplication sharedApplication] delegate] window];
window.rootViewController = theInitialViewController;
To swap views Programatically you would need to select the segue and give it an Identifier like "PushView" then call it like this ....
[self performSegueWithIdentifier:#"PushView" sender:self];
That will programatically do the same as clicking the forward button. I've created you an example project with the code discussed above. Has an -(IBAction) with code in you can use for programatially changing the view.
PushView.zip
I also wanted to do this, present a screen (that had an embedded navigation controller) when the user pushes a button.
At my first attempt, I connected the segue from the button in the fist screen to the Navigation Controller, and the app was crashing with this error "Pushing a navigation controller is not supported".
This is the solution I found:
Select the segue from the button in the first screen to the navigation controller.
If it had an identifier, copy its name. Then delete that segue.
Then create a new segue by CTRL-clicking the button in the first view controller and dragging to the VIEW CONTROLLER YOU WANT TO PRESENT (not to the Navigation Controller that is pointing at it), and select Push in the small pop up window.
Then click the icon in the middle of the segue and paste the name you copied in the first step as an identifier for it.
IB is going to give you a warning "Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:." Don't worry, it works perfectly.
If you want to customize the string that is shown as the Back button to return, you can add this line in the viewDidLoad method OF THE VIEW CONTROLLER THAT IS BEING SHOWED AFTER THE BUTTON IS PRESSED, that is the Child view controller.
(replace "Settings" with the name you need)
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.topItem.title = #"Settings";
...
}

Help in presenting navigation controller

I need help on some logic.
This is how my application is structured.
Welcome View Controller > Login View Controller > Tab Bar Controller > Feed Navigation Controller
So, i used presentmodal for the transition of Welcome View Controller to Login View Controller.
using [self presentModalViewController:loginVC animated:YES];
So now i'm in Login View Controller. But how to i navigate to the Tab Bar Controller which will show the rootviewcontroller of the Feed Navigation Controller?
I tried [self presentModalViewController:tabBarController animated:YES];
But i'm not getting the navigation controller in it!
Thank you!
If TabBarController is your rootController, then your implementation is probably wrong.
Have the Welcome Screen as your ModalViewController and Navigate to LoginScreen, and perform necessary actions.
if (LoginSuccessful)
// Dismiss modalview controller
This will bring control back to your rootController, and you do not need to navigate from welcome to login to tab bar and stuff like that.

loading a UINavigation controller from a UIView

i am designing an app that has a login screen. it is a UIView with username/password and a button to submit. once the user authenticated successfully, i want to load a new xib file that holds a navigation controller and a navigation bar. below the bar i want to load a tableView and switch between other views as i move along with the programming of it.
what i did is create a new class that inherits from UINavigationController and assembled the xib file to include the navigation controller. i hooked it back up to file's owner and i'm loading the navigation controller modally like this:
myNavController* navVC = [[myNavController alloc] initWithNibName:#"navXibFile" bundle:nil];
[self presentModalViewController:navVC animated:YES];
[navVC release];
this works okay as the navigation controller shows up. however, it shows up with no title, even though i've set one up in IB. moreover, the tableView's delegates are hooked up via IB but i cannot even see empty lines. all i see is an empty navigation bar at the top and blank view (one piece) below it.
thank you for your help.
so i figured it out... first it's a design decision right? is the app being managed by a navigation controller? if so (which is my case), expect the main (first) view, that is a login page, all you need to do is to hide the navigation bar in your ViewdidLoad for the main view:
[self.navigationController setNavigationBarHidden:YES animated:YES];
once the user logs in and you push the next view like this:
MainTableViewController* mainTableVC = [[MainTableViewController alloc]
initWithNibName:#"MainTableViewController" bundle:nil];
[self.navigationController pushViewController:mainTableVC animated:YES];
[mainTableVC release];
and lastly, in the ViewDidLoad of the next view controller:
[self.navigationController setNavigationBarHidden:NO animated:YES];
in case your app needs a navigation controller for a specific section of the app but not all if it, you will need to use the VC to manage this, in a similar way the appDelegate manages the sample navigation based sample app.
i hope this helps anyone struggling with wrapping their minds around the design patterns implemented here.
cheers.

UINavigationController without NavigationBar

I have a "landing page/view" that I dont want the navigation bar to show, so I turn it off during the viewDidAppear
navigationBarHidden = YES;
When i push a view on the stack and then move it off. the main landing page shows the nav bar then hides it which cause a flicker that I dont want.
is there a way to have the landing page be a UIView or something? When a menu item is touched the app would push a new view on top of the default landing page. It sound like it would be hard to do without having the landing page be a UINavigationController. Any thoguhts?
Try hiding the navigation bar in viewWillAppear, rather than viewDidAppear.
If you don't need to go back to the landing page, use a view controller for the landing page and present it modally from the navigation controller when the application starts.
So you do want to go back to the landing page.
It's hard to accomplish that with UINavigationController. Suppose your are going back to the landing view. While the transition, the old view should have a navigation bar, and the new view (landing page) should not have a navigation bar. UINavigationController does not allow you manually modifying the transition animation. In other words, you cannot animate hiding/unhiding the navigation bar along with push/pop animation (using viewWillAppear doesn't solve the problem).
So what would I do, if I really, really need this?
I would have a rootViewController (of UIViewController), whose view is the only subview of your application window. When your application starts, rootViewController add the landing view as a subview of its view. When the user selects an item there, you create an UINavigationController with the corresponding view controller as its root view controller.
And, using CATransition animation with type of kCATransitionPush and subtype of kCATransitionFromRight, you add the view of the navigation controller as a subview of rootViewController's view.
Then you need a 'back' button for the first view of the navigation controller. In all view controllers that are the first level view controllers of the navigation controller, create a bar button item with a text 'Back', and add it to their navigationItem.leftBarButton property. Set a target-action (probably to the rootViewController) pair for the button.
When the action message fires, use CATransition animation (now with kCATransitionFromLeft subtype), to remove the current navigation controller's view from rootViewController's view.
The transition may not look as perfect as the native UINavigationController, but I believe this is the best you could get.
Actually the way to do this is to implement UINavigationController's delegate method navigationController:willShowViewController:animated. This method is where you should handle hiding and showing your navigation bar so the animation will occur during the push/pop animation.
I came across a method that is simple and works well for me, and is not given here yet. I assume you have a view controller for the main landing page and it is set as root view controller of the navigation controller. Then you should hide/show the navigation bar in the viewWillAppear and viewWillDisappear methods of the main landing page controller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
Source:
http://www.iosdevnotes.com/2011/03/uinavigationcontroller-tutorial/