Unable to present a modal view controller completely over the top of a tab bar controller - iphone

I'm creating a tabbed iPhone application. When the application launches, if the user is not logged in, a modal view is supposed to be presented over the top of the tab bar controller (so it looks like this is the first screen). Upon login the modal view slides away to reveal the tab bar controller behind it.
Unfortunately when I call [self.tabBarController presentViewController:self.loginViewController animated:NO completion:NULL] from inside my application delegate I can still see the tabs along the bottom of the screen. I need them covered.
Ironically when searching for a solution, I find most people are having the inverse problem.
I have noticed that if I don't set my window's rootViewController to the UITabBarController, only inserting its view as a subview of the window, then it works as expected, but Xcode complains about the lack of rootViewController. What's going on here?
My application delegate's -application:didFinishLaunchingWithOptions: method looks like this.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self registerDefaults];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[
[self makeSellingListingsController],
[[[UIViewController alloc] init] autorelease], // stub
[[[UIViewController alloc] init] autorelease], // stub
[[[UIViewController alloc] init] autorelease] // stub
];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.rootViewController = self.tabBarController;
[self.window addSubview:self.tabBarController.view];
[self presentLogin]; // this doesn't cover the tabs, but it should
[self.window makeKeyAndVisible];
return YES;
}
- (void)presentLogin
{
[self.tabBarController presentViewController:[[[FLLoginViewController alloc]
initWithNibName:#"FLLoginViewController"
bundle:[NSBundle mainBundle]] autorelease]
animated:NO
completion:NULL];
}

Don't present it from the tab bar controller, but from the root controller in the first tab, in its viewDidAppear method. If you pass NO to the animation parameter, the modal screen will be the first thing you see when you start the app.

Related

Tab bar disappearing when drilling down through navigation controller

I've setup an App that has a Tab Bar controller as a screen in a navigation controller using the storyboard. I can navigate to it fine, but when I start drilling down through screens in one of the tabs, the tab bar disappears. If I navigate back to the first screen the tab bar is supposed to be on, the tab bar will reappear, but I would prefer if it was visible on the child screens. Is this possible or do the two view controllers just not play well together?
The tab bar controller always needs to be the root view controller. You can't put it INSIDE a navigation controller.
Even if it was possible, it wouldn't be good user interaction. What is it you're trying to do exactly (functional)?
I think what you want is to place the navigation controller as the first tab inside the tab bar controller instead. (not the other way around like you're describing)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MenuViewController * menuViewController=[[[MenuViewController alloc] initWithNibName:#"MenuViewController_iPhone" bundle:nil] autorelease];
menuViewController.hidesBottomBarWhenPushed=YES;
//menuViewController You can have your option here
UINavigationController * navigationController;
UINavigationController * navigationController2;
UINavigationController * navigationController3;
viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:nil] autorelease];
viewController2 = [[[SecondViewController alloc] initWithNibName:#"SecondViewController_iPhone" bundle:nil] autorelease];
navigationController=[[UINavigationController alloc] initWithRootViewController:viewController1];
navigationController2=[[UINavigationController alloc] initWithRootViewController:viewController2];
navigationController3=[[UINavigationController alloc] initWithRootViewController:menuViewController];
UITabBarController * tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:menuViewController,navigationControllerFirst, viewController2, nil];
//self.tabBarController.tabBar.tintColor=[UIColor orangeColor];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return true;
}

View is not displaying after pushing on navigationController stack

I am trying to use a navigation controller to push/pop views, but I don't want the bar at the top with the buttons; I'm doing the navigation UI myself.
So I created a navigationController in my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[WSViewController alloc] initWithNibName:#"WSViewController" bundle:nil];
self.window.rootViewController = self.viewController;
self.navController = [[UINavigationController alloc]
initWithRootViewController: self.viewController];
[self.window makeKeyAndVisible];
return YES;
}
and then in my WSViewController, I have an IBAction method that pushes another view on the navigation stack (I've verified that it's doing this correctly; I see it on the stack):
- (IBAction)showInfo:(UIButton *)sender {
if (self.wsInfoViewController == nil) {
WSInfoViewController *wic = [[WSInfoViewController alloc] initWithNibName:#"WSInfoViewController" bundle:nil];
self.wsInfoViewController = wic;
}
[self.navigationController pushViewController:self.wsInfoViewController animated:YES];
}
But I'm not seeing the info view show up when I tap on the info button in my WSViewController (which is showing up just fine).
If I make the navigationController the root controller, then I do see the wsInfoViewController when I tap on the info button, however, I also get the navigation bar at the top, which I don't want!
So... first, am I wrong in thinking I can use a navigation controller this way (i.e. using it for stack purposes but not for any UI at all)?
Second, if I'm not wrong, why isn't the view I'm pushing onto the stack showing up? I'm guessing it's because I'm not hooking the navigation controller up to the window correctly, but I'm not sure how to do that.
Thanks!!!
Elisabeth
So I think I have the answer to my question. Which is, you must set up the navigation controller as the root view controller for the AppDelegate window in order to use it, otherwise, the window doesn't know about it. My WSViewController is still the root view controller for the navigation controller. And then to get rid of the navigation bar, you can hide it.
Here's the updated code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[WSViewController alloc] initWithNibName:#"WSViewController" bundle:nil];
// doesn't work!
//self.window.rootViewController = self.viewController;
self.navController = [[UINavigationController alloc]
initWithRootViewController: self.viewController];
// do this instead
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
return YES;
}
To hide the nav bar in the views, in each view where you want it hidden, add the following methods:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
This is working great so far!

iPhone: pushViewController doesn't work after replacing RootViewController

I wish to place a screen before my curren RootViewController. So far I have made the following modification to MyAppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//with this in the existing RootViewController loads correctly
//self.window.rootViewController = self.navigationController;
self.window.rootViewController = [[[HomePageController alloc] init] autorelease];
}
I'm not entirely sure how self.navigationController actually gets set to my RootViewController. Either way if I make the modification my HomePageController does load correctly, however I am then unable to push another view on top of it. I have a simple button on HomePageController that performs the following (note that HomePageController should load the currently named RootViewController, HomePageController is the view I want to sit above this):
RootViewController *rvC = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]] autorelease];
[self.navigationController pushViewController:rvC animated:YES];
When this code runs nothing happens... I'm not entirely sure why, possibly something related to the navigationController? Maybe I havent put HomePageController above RootViewController correctly or in the best way?
You have no navgiationController currently installed.
To fix you have to replace
self.window.rootViewController = [[[HomePageController alloc] init] autorelease];
with
self.window.rootViewController = [[[UINavigatoinController alloc] initWithRootViewController:[[[HomePageController alloc] init] autorelease]] autorelease];
now you have navigationController installed and following
[self.navigationController pushViewController:rvC animated:YES];
will do the right job.

Show login screen before tab-controller view

i have a tabBarController application and using .xib files for the interface not the storyboard
i have this code by default in the appdelegate
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[PopAdsFirstViewController alloc] initWithNibName:#"PopAdsFirstViewController" bundle:nil];
UIViewController *viewController2 = [[PopAdsSecondViewController alloc] initWithNibName:#"PopAdsSecondViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
i have created a Login View and don't know how to show it before the tabBarView and hide t after a successful login.
One way would be to show it as a modalView on launch. Dismissing upon successfull login?
eg:
UIViewController myLoginViewController = [[MyLoginViewController alloc] init withNibNamed:"MyLoginViewController"]; //Or whatever you instantiation is
[myTabViewController presentModalViewController:myLoginViewController animated:YES];
And to dismiss it (Hide it)
//This should be done from the original View Controller i.e. myTabViewController preferably in a delegate called by the modal view controller.
[self dismissModalViewControllerAnimated:YES];
Documentation on modalViewControllers:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html
The way that I did it for one of my apps is to just add them in the correct order. Add your tabbar controller to your window, then add the login controller over the top of the tab bar. Then show your window. The user won't see anything but your login controller. Once you login, you can just remove the login controller from view.
This way is probably best if you have information you need to hide until login. The other way is to only launch the login view only. On successful login, remove the login and add the tab bar controller. Either way is fine.
Presenting modally is probably the easiest, but requires a view in place before presenting. So if the data and view under the login controller isn't that sensitive, you could consider this option.
Another way would be using LoginViewControllerDelegate in your appDelegate.h file
In your .h
#import "yourLoginViewController"
//and add LoginViewControllerDelegate
Then in your .m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
yourLoginViewController *loginView = [[yourLoginViewController alloc] initWithNibName:#"yourLoginViewController" bundle:nil];
loginView.delegate = self;
[window addSubview:loginView.view];
[window makeKeyAndVisible];
}
//add this one
- (void)loginViewControllerDidFinish:(yourLoginViewController *)loginViewController {
[window addSubview:tabBarController.view];
}

How to show UINavigationController on view

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
UINavigationController *nav_obj = [[UINavigationController alloc] initWithRootViewController:overviewViewController ];
[self.viewController presentModalViewController:nav_obj animated:YES];
[overviewViewController release];
[self.window makeKeyAndVisible];
return YES;
}
This code shows the blue bar of navigation controller, but no buttons on it.It seems like to be that the UINavigationController allocated as empty.
Who knows what problems is?
UPD:Archive http://www.mediafire.com/?lbjjvl6fcue2q18
Please help me, I'm new in objective-c
You need to create the button for it, for example:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:launcherView action:#selector(endEditing)];
self.navigationItem.leftBarButtonItem = doneButton;
[doneButton release];
The correct way to use a UINavigationController is to push view controllers on to it. That way they will be stacked and the navigation bar will be populated with a back button when it is case (i.e., when you can actually go back to a previous controller). You control the label that appears in the "back" button by defining the title of the controllers you push.
The technique shown in another answer (setting explicitly the button) is useful with defining the right button, if you ever need one.
You could try with this code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
UINavigationController* navigation = [[UINavigationController alloc] init];
[navigation pushViewController:overviewViewController animated:NO];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
Instead of doing:
UINavigationController* navigation = [[UINavigationController alloc] init];
[navigation pushViewController:overviewViewController animated:NO];
you could also use initWithRootController, but to display the general case of how you push a view controller I preferred this one.
Notice that since you are pushing just a root controller, you should see no back button at the moment, but if you push a second view controller, then it will appear.
EDIT: I gave a look at your project. Summary of what you should try and do:
objects you need in your NIB: File's Owner (UIApplication), First Responder, FBFun App Delegate (iVkAppDelegate), Window (UIWindow); remove the rest;
File's owner delegate outlet is FBFun App Delegate;
FBFun App Delegate window outlet is Window.
With this simple setup (more or less what you have), use this code :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UINavigationController* navigation = [[UINavigationController alloc] init];
//-- MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
iVkViewController *overviewViewController = [[iVkViewController alloc] init];
overviewViewController.title = #"First";
[navigation pushViewController:overviewViewController animated:NO];
iVkViewController *overviewViewController2 = [[iVkViewController alloc] init];
overviewViewController2.title = #"Second";
[navigation pushViewController:overviewViewController2 animated:NO];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
In the code above, as you notice, I instantiated twice your iVkViewController just to have a second controller to push onto the navigator.
Please, delete your existing app from the simulator, and the run this in order to see that the navigation bar is correctly created and you can go back from the second controller to the first one.
I removed usage of MainPageDialog, because the MainPage nib has many problems.
But I hope this skeleton is sufficient for you to go forward with your development.
You had missed the line as you are not adding view to window.Add this line in your code
[window addSubview:nav_obj.view];