I am in the process of creating an application. In the main ViewController I have created the menu. But I want to have a login screen (UIView) to appear before the menu is visible.
But because the menu loads as soon as I run the application I have decided to create another UIView controller and have that loaded on top of the main ViewController.
Therefore at the end of my main ViewController viewDidLoad I have added the following code to open on top of that view the login view
LoginPageView *loginPageView = [[LoginPageView alloc] initWithNibName:#"LoginPageView" bundle:nil];
loginPageView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:loginPageView animated:YES];
As I know the purpose of that code is to present another view, but unfortunately the login view does not appear. Only the main ViewController load.
Can anyone help me on that? Have you realised what exactly I want?
Thanks a lot
In the viewDidLoad method, the view exists, but there is no guarantee that the view is already part of the view hierarchy of your application. In fact, almost ain't.
What you can try is take that code in the viewWillAppear: or viewDidAppear:.
Make a UINavigationController. Use this as your window's root view controller. Set the UINavigationController to not show the navigation bar.
Set the navigation controller's child view controller to your login view controller.
When the user logs in successfully, create your main view controller and push it, like this:
MainViewController *mainVC = [[MainViewController alloc] initWithWhatever...];
[self.navigationController pushViewController:mainVC animated:YES];
When the user logs out, you can just do this to get back to the login VC:
[self.navigationController popViewControllerAnimated:YES];
Related
I know this has been asked a million times, but I couldn't find a suitable answer in those many questions that I've examined.
I have a custom view controller, and I'm trying to display the view controller when the user taps a button (so no "infamous viewDidLoad problem" here).
Here is my code that runs when the user taps the button: (I have the NIB for the view controller, and I have a navigation controller)
ICLoginViewController *loginViewController = [[ICLoginViewController alloc] initWithNibName:#"ICLoginViewController" bundle:[NSBundle mainBundle]];
//assuming we have a navigation controller.
UINavigationController *navigationController= (UINavigationController*)[[UIApplication sharedApplication] keyWindow].rootViewController;
[navigationController.topViewController presentViewController:loginViewController animated:YES completion:nil];
I'm getting the Warning: Attempt to present <ICLoginViewController: 0xa08a810> on <UINavigationController: 0xa45de70> whose view is not in the window hierarchy! error when I try to present the view controller. Nothing happens on screen. If I tap multiple times I get the same error, and still nothing happens. I've set a breakpoint and verified that navigationController and navigationController.topViewController are not nil. I' using storyboard (if it helps) but not for the custom view controller that I'm trying to display. (I want to make it an app-independent library in the long run, so I'm not referencing any app-specific modules within) Why am I getting this error?
I've found the solution. The problem was, my modally displayed view controller was not the 'top' view controller in navigation controller. If I change the calling view controller to be pushed instead of being modal, then it becomes the top view controller and my app works well. Apparently, this had nothing to do with my custom view controller, but my navigation stack.
If its in an NSObject create a method inside the NSObject that takes your current viewController as an argument and present it there.
eg:
-(void)presentInViewController:(UIViewController *)controller{
ICLoginViewController *loginViewController = [[ICLoginViewController alloc] initWithNibName:#"ICLoginViewController" bundle:[NSBundle mainBundle]];
[controller presentViewController:loginViewController animated:YES completion:^(BOOL comp){}];
}
This way you can call that view controller wherever you want instead of trying to find your way through the navigation stack from UIApplication.
I would like to combine UITableView and UINaviationController in an app but as a newbie most apps I've seen just send you straight to the results view (UITableView). But, I guess a "normal" search application does not assume you have the results on the first screen. There should be a search form on first screen with input fields and a button that triggers the search process and show some results and navigation.
So, I'm just trying to replicate this normal behaviour in my app. I've already made the search form (no navigation shown on it, of course) and a seperated View called "ListingViewController" with its related View and containing a UITableView and where I think I should add the Navigation...The next idea will be to make a DetailViewController and possibly and ListingMapController to show the listing in a GoogleMap.
So, where I'm stuck at is how to add this Navigation Controller ?
Some suggested me to add it in the SearchViewController delegate...
But I don't want a navigation on search form of course...
Some suggested me to open the Navigation controller modally...
But, I"m also planning at adding a Tab Bar to allow user to see other informations (like About,etc...) and with a modal Nav controller I don't know if they will still see the bottom Tabbar...
Any suggestions? What do you think is of best practices especially to avoid my app of being rejected by Apple?
Thx in advance for reading and helping!
Stephane
You could init the navigationController with your View Controller as the root view Controller. Then hide the navigationBar (if you need to). You would then add the navigationController.view as the subview. This will basically look like the original view controller. Then you can pushViewController: animated: to push the results view Controller.
So, for example in your AppDelegate (or in the proper view controller):
Create a property and ivar for a UINavigationController and hook up its outlets in interface builder. Then set your search controller as the root view controller for the nav bar, and add it as a subview.
MySearchViewController* searchController = [[MySearchViewController alloc] init];
self.myNavigationController = [[UINavigationController alloc] initWithRootController:searchController];
[searchController release];
self.myNavigationController.navigationBarHidden = YES;
[self.window addSubview:self.myNavigationController.view];
[self.window makeKeyAndVisible];
Then of course in your searchController, you would simply say:
ResultsViewController* myResultsViewController = [[MyResultsViewController alloc] init];
//You may want to create another init method and pass in some arguments like an array:
// [[MyResultsViewController alloc] initWithResults:results];
then push the viewController
//This is in your search controller class
[self.navigationController pushViewController:myResultsViewController Animated:YES];
[myResultsViewController release];
from the results viewController, to get back you pop the view controller off of the navigationController view controller's stack.
//In results view controller perhaps in some IBAction for a back button:
-(IBAction)backButtonPressed:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
I currently have an application that does the the following:
S: Loads a view as a login screen to start with.
a: If login is successful I add a terms and conditions screen as a subview
b: If not successful I add a sign up form as a subview
F: Then I load the main part of my app on success of either of the a or b which is the part of the app where there is a navigation controller and a tab bar controller. This is set up in MainWindow.xib
S, a and b also have Nav bars but no navigation controllers as I didn't think I would need navigation control on the login screens.
However it turns out I do, I want to be able to have back navigation from both a and b to the initial login screen.
I have tried several ways of doing this including trying the following answers:
How to add navigation controller in View Based Application in iPhone?
How do you properly set up a secondary view to support a navigation Controller on the iPhone?
how to add navigation controller programatically?
But none of them work for me, they display the new Navigation controller over the login screen and dont load the a or b screens.
I'm guessing this is because I am adding them as subviews to my loginView and this is not the correct way to do this? My code is as follows:
if(self.tcSubViewController == nil){
TCSubViewController *_tcSubViewController = [[TCSubViewController alloc] initWithNibName:#"T&CView" bundle:[NSBundle mainBundle]];
self.tcSubViewController = _tcSubViewController;
[_tcSubViewController release];
}
[self.view addSubview:[tcSubViewController view]];
I'm guessing there's a fundamental flaw in the way my Login flows? I should be able to completely remove the LoginView and then display the Terms and conditions view without having to add it as subview, shouldn't I?
You need to dismiss the navigation controller to go back to.
To dismiss modal view:
1.Easy way: In your modal view in some method that you call to dismiss just add:
[self.navigationController dismissModalViewControllerAnimated:YES];
2.More complex way: Implement and delegate protocol on your modal view and make the view controller that presents the modal view the delegate of it. And in the delegate method dismiss the modal view. I do this way when I need to send data from modal view to the controller that present it.
Reference to this post
Navigation controller philosophy is that you add only navigationController.view as UIWindow subview and it wil manage the rest by itself. You only need to push/pop viewControllers and their corresponding views will be added/removed from screen automatically.
sample code from my current application:
HomeController *homeController = [[[HomeController alloc] init] autorelease];
self.controller = [[[UINavigationController alloc] initWithRootViewController:homeController] autorelease];
self.controller.navigationBarHidden = YES;
[self.window addSubview:self.controller.view];
[self.window makeKeyAndVisible];
and then to push next view you just add next controller:
[self.navigationController pushViewController:newController animated:YES];
I am using a split view controller in an iPad app I am trying to make.
Right now, I have a view being displayed in a modal view controller using:
[self presentModalViewController:viewController animated:YES];
and that works fine, but when the user presses a button, I want the root view controller to push to another view. I am using:
RootViewController *rvc = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
[rcv pushViewController:rvc animated:YES];
but that is not working. What should I do?
--EDIT
Now, I am using
PhotosViewController *pv = [[PhotosViewController alloc] initWithNibName:#"PhotosViewController" bundle:nil];
[self.parentViewController.navigationController pushViewController:pv animated:YES];
NSLog(#"Navigation Controller: %#", self.parentViewController.naviagtionController);
When I do the NSLog call, it returns nil. Why is that?
Once again, I am using a split view controller and am trying to push the RootViewController to a new view.
Thanks
Your code isn't working because you're created a RootViewController instance and then trying to push it onto itself. What you should be doing is pushing the new view controller onto the parent view controller's navigation controller:
[self.parentViewController.navigationController pushViewController:newViewController animated:YES];
I know this is an old question but I believe the proper way "now" to push a viewController onto the main navigation stack from a modal viewController is to create a "didTapShowBlahViewController" delegate on the modal (this is assuming you want the user to be finished with the existing modal view and then push a new view onto the stack). Once you have that delegate, you simply have the view that initially invoked the modal to perform dismissing the modal and pushing the next view controller when the delegate is triggered.
- (void)didTapShowBlahViewController{
[self dismissViewControllerAnimated:YES completion: nil];
[self performSegueWithIdentifier:#"segueToBlahViewController" sender:self];
}
This is based on Apple's View Controller Programming Guide that specifies passing data to child view controllers and using delegates to pass data back to parents.
FYI: This way also ensures that the "back" button will not go back to the modal but instead to the view that invoked the modal, which is how modals are typically used.
In my app, I require the main page to contain a toolbar at the top of the view. This view has a tableView. So my application cannot have a NavigationController.
Problem
When I want to navigate to the other view on click of the tableview cell then I am using the "pushViewController:animated:" method but it doesnt seem to work.
I checked the connections in IB. They are fine.
How can I navigate between pages without navigation controller??
I do not want to use the modal view for other views.
Please Suggest some Method.
You can use an instance of UINavigationController without having it displayed and using it for navigation.
Load your first view controller with your instance of UINavigationController in your appDelegate implementation.
Like:
FirstScreenController *fsc=[[FirstScreenController alloc]initWithNibName:#"FirstScreenController" bundle:nil];
UINavigationController *navigation=[[UINavigationController alloc]initWithRootViewController:fsc];
navigation.navigationBar.hidden=YES;
[window addSubview:navigation.view];
Here FirstScreenController can be your view controller having the toolbar and tableview.If you want to display another view on any click of the tableviewcell, call it this way.
[self.navigationController pushViewController:secondviewcontroller animated:NO];