I'm coding an iphone app and I've an issue on how to manage views presentation. Indeed, when user starts the app a "home" View shows up containing a search form. When user presses a "search" button I want a method to open a navcontroller that displays the search results. I made another view containing a TableView with the purpose of serving as "results" View. I want the "results" view to allow user to go back to the "home" view (the search form) but I don't want the "home" view to have a navigation controller bar...
Any idea on how to solve this ?
Thx in advance,
Stephane
The easier way is just to hide the navigation bar on the 'home' view and show it back on the other view...
You have to create a UINavigation controller manually and present it modally as follows:
MapViewController *mapViewController = [[[MapViewController alloc] init] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mapViewController];
[self presentModalViewController:navController animated:YES];
Related
I am working on an application for IOS .I made a menu bar which contains buttons , menu bar should be on each page of application. I made many View controller scenes , I want the functionality like this : when i click on any button it should open a View controller scenes.
How to open a View controller scenes on click of button ? I don't want to add other existing View controller scenes on my current View controller scenes as a subview. I want to open other existing scenes independently.
You have to look into the following
Navigation controller
Tab bar controller custom implementation
Have you tried this, just replace YourViewController with the name of the .xib you would like to load.
YourViewController *yvc = [[YourViewController alloc] init];
[self presentViewController:yvc animated:YES completion:nil];
This goes inside your IBaction for the navigation button, fyi.
You need to look into UINavigationController or UITabBarController. There are other ways too. The navigation controller is the easiest. Apple documentation has everything you need.
1) Insert View :
ButtonView *buttonView = [[ButtonView alloc] initWithNibName:#"ButtonView" bundle:[NSBundle mainBundle]];
buttonView.view.frame = CGRectMake(yourFrame);
[self.view addSubview:buttonView.view];
2) Remove View :
[buttonView removeFromSuperview];
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];
}
Everyone
I have a problem and I have been searching the solution but could not find any. I am working on a tab bar based app. Problem is that I want to hide tab bar at first screen and then show it on all other screens that are being displayed after first screen.
Can anyone please give me the best solution for this problem?
Actual scenario is that I have a screen that is login screen. Now i dont want to show tab bar here as tab bar will be displayed only if the user is signed in. When user logs in, I want the tab bar to be displayed showing its contents.
Best Regards
If you have your Tab Bar Controller as your rootController, you can use rootController.selectedIndex =0 for selecting 1st Tab bar Item, and rootController.selectedIndex =1; and so forth.
As soon as that particular view loads, you can load the other views in an array, and then add it to the rootController.selectedIndex and reloadInputViews with animation.
Edit: (as per the comments)
So you have a tab bar controller, and you want to show the introduction and the login screen while starting the App. If login is successful, you want to present the tab bar controller ! This can be done with ModalViewControllers
In the ViewDidLoad of the view that loads up first, (it's your first tab by default), add
//Declare Introduction Screen//
IntroductionController *introductionController = [[IntroductionController alloc] initWithNibName:#"IntroductionController" bundle:[NSBundle mainBundle]];
//Give a navigation screen for your introduction screen and set it to introduction screen
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:introductionController];
navController.title = #"Introduction";
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navController animated:NO];
Now your introduction screen would load as soon as your first tab bar loads. But the loading is instantaneous, so it's not visible to the user's eye. Now reference your Login View Controller like #class LoginController and create an object LoginViewController *lvc;, and synthesize it. Now declare LoginButton and in the IBAction
-(IBAction) loginAction: (id) sender{
NSLog(#"I clicked Login");
if (self.lvc ==nil){
self.lvc = [[LoginController alloc] init ];
}
lvc.title = #"Login";
[self.navigationController pushViewController: self.lvc animated:YES];
}
And in the LoginViewController, if Login is successful, just do
[self dismissModalViewControllerAnimated:YES];
create an outlet for the uitabbar, then declare it hidden in the first screen, then create a new void, NOT SENT SO IT DOESNT WORK in the first screen, make it say, lets say, hide. And inside hide, put code saying your uitabbar.hidden = YES; then, to make it work in the other view, write this in the viewDidLoad:
[(//first view*)[UIApplication sharedApplication].delegate //the void, in this case, hide];
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];
In a custom UIViewController, if I have a member UINavigationController that I initialize with self as the root view, like this:
navController = [[UINavigationController alloc] initWithRootViewController:self];
then presenting a modal dialog does not hide the tab bar at the bottom of the screen. The result is that if the user switches to a different tab while a modal dialog is displayed, when they pop back to the tab that was displaying a modal dialog then subsequent calls to presentModalViewController do not display a modal dialog at all, even if I call dismissModalViewControllerAnimated as a result of the tab switch.
If I initialize the UINavigationController with out setting self as the root controller,
navigationController = [[UINavigationController alloc] init];
then the tab bar is hidden as expected. I've changed things in my program so that this isn't really an issue for me anymore, but I'm not sure that I understand why this is happening. Is it considered bad practice to have a navigation controller with self as the root, if the nav controller is going to be displaying modal dialogs?
I never added self as root controller
I always have some Controller that gets a NavigationController.view added to itself.
And the first ViewController that shall be displayed in the Navigation hierarchy I then add as the rootViewController. It's just another word for "first page" (in the beginning all the naming can be quite confusing).
Example in MyProjectAppDelegate.m:
UITableViewController *startScreen = [[UITableViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:startScreen];
[window addSubview:navController.view];
You also shouldn't mix UINavigationController with UITabBarController, if you want to have a tab bar in a navigationcontroller "page" you can build a custom UITabBarController.
This would show you how http://github.com/wiredbob/NavTab
(I had big problems in understanding all this view/controller nesting myself and this project really made the difference. You could say this was the code I really learned how to programm for iPhone/Mac with :DD )