My app is designed using a UITabBarController and im trying to present a view on top of that (a login screen) from the app delegate. When i use the following code:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
tabBarController = [[UITabBarController alloc] initWithNibName:#"Main_TabBarController" bundle:nil];
self.window.rootViewController = tabBarController;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
Login_ViewController *lvc = [storyboard instantiateViewControllerWithIdentifier:#"Login_ViewController"];
[self.window.rootViewController presentViewController:lvc animated:YES completion:nil];
I get the error Warning: Attempt to present <Login_ViewController: 0x716fac0> on <UITabBarController: 0x7165240> whose view is not in the window hierarchy! and the screen is just black. How do i add Login_ViewController to the window hierarchy?
You can always grab the current root viewcontroller and use it to present your login controller.
UIViewController *presentingController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[presentingController presentViewController:viewController animated:YES completion:nil];
In addition, depending on how I want my login screen to look, I will push the login controller using UIModalPresentationFormSheet.
viewController.modalPresentationStyle = UIModalPresentationFormSheet;
You're using two different mechanisms for creating your UI. You should move your tab bar controller into the storyboard. When you instantiate your storyboard, it overwrites your window with a new instance and the first controller as the root controller.
The error message is telling you the tab bar controller's view is not in the view hierarchy, not the other way around.
I would create a controller with a view consisting of just your application logo and inside of this controller determine whether you need to go to the login screen or not (if you have persistent logins). Then from the login screen transition to the tab bar controller.
Unless the storyboard you're loading isn't the main storyboard, you shouldn't need to load it manually. You should be able to set the storyboard as the main one for the application and iOS will load it automatically.
Related
I am trying to create a tabview project with three tabs (A,B,C). Tabs A and C are tableview controllers which work well. Tab B I want to make a ViewController that will use the camera using a AVCaptureSession. The question I have is how do I make Tab B display the camera modally over the tabview?
You could just present any modal controller without animation in viewDidLoad or viewWillAppear.
UIViewController *vc = [[UIViewController alloc] init];
vc.view.frame = [[UIScreen mainScreen] bounds];
vc.view.backgroundColor = [UIColor purpleColor]; // for testing
[self presentViewController:vc animated:NO completion:nil];
In that view controller you can do whatever you like, including starting a AVCaptureSession.
In order to return to the previously selected tab controller there are several options.
One is to switch to the desired tab when dismissing the modal view controller. Suppose it has a property or ivar called lastTab:
self.tabBarController.selectedViewController
= [self.tabBarController.viewControllers objectAtIndex:lastTab];
Another way is to never actually activate the tab with the modal view but launch the modal view controller directly from the other tabs. The other view controller could set the selected tab back to itself and then launch the modal view.
In my codes, I wrote it in this way
DetailView *vc = (DetailView *)[mainStoryboard instantiateViewControllerWithIdentifier:#"DetailVC"];
self.window.rootViewController = vc;
It only show that view but I don't see the navigational bar and tab bar.
What is the right way to open a specific view (inside tabbarcontroller) within storyboard when the app receive remote notifications automatically?
That's because you get only DetailView from storyboard. If you want to show it inside navigation controller you have to init this controller.
DetailView *vc = (DetailView *)[mainStoryboard instantiateViewControllerWithIdentifier:#"DetailVC"];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController: vc];
self.window.rootViewController = navVC;
But I think the issue is in other. You instantiate wrong view controller. You should instantiate tab bar controller or navigation controller and then only select proper tab.
i want to change display to an UIViewController which has view controller at storyboard from an UIViewController class which hasn't got view controller at storyboard. There is no segue at storyboard for this...
Just like this:
In your AppDelegate.m do a quick setup:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
ViewController *sourceViewController = [[ViewController alloc] init];
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:sourceViewController];
[self.window setRootViewController:nav];
return YES;
}
In above example replace ViewController class with your own class of sourceViewCntroller
- (IBAction) didPressMyButton {
NewViewController* newVC = [[[NewViewController alloc] init] autorelease];
[self.navigationController pushViewController:newVC animated:YES];
}
Connect this action to a button on storyboard or embed view change in any method. You will need to setup UINavigation controller first.
I'm not completely sure I understand what you're trying to do, but I think you are asking how to load a view controller from a storyboard, without using a segue, from a method in a view controller that wasn't loaded from the storyboard.
First, in your storyboard, select the view controller you want to load, and open the Identity Inspector. Set the Storyboard ID of the view controller. It looks like you want to load a MapViewController, so let's say you set the storyboard ID to map.
In your code, you can load the view controller like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MapViewController *mapViewController = [storyboard instantiateViewControllerWithIdentifier:#"map"];
Once you have a reference to the view controller, you can set its properties or send it messages. You can then display it in whatever way you want - maybe by pushing it onto a navigation controller, or by presenting it, or by setting it as the root view controller of your window.
Hey guys i`m trying to present a modal view controller inside an application with a tab bar controller. The problem is, every time the new view is presented, it on top of my tab bar.
I need to keep my tab bar even when the view is presented. Like google maps application does with his toolbar at the bottom of the screen.
How can i do that?
Thank you
By default, a modal view controller is meant to take up the entire screen (on an iPhone/iPod, at least). Because of this, it covers whatever you have on screen at the time.
A view controller presented via modal segue is meant to live on its own. If you want to keep your Navigation and TabBar, then just use a push segue to present the new ViewController. Remember to use this kind of segue, your presenting controller needs to be part of a UINavigationController already.
Use this to push a ViewController. If it is a UINavigationController it will push its linked RootViewController by itsself.
Create a viewController to push: (Using Storyboard)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
or (Using Code/Nibs)
LoginViewController *viewController = [[LoginViewController alloc] init]; //initWithNibNamed in case you are using nibs.
//in case you want to start a new Navigation: UINavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
and push with:
[self.navigationController pushViewController:vc animated:true];
Also, if you are using Storyboards for the segues you can use this to do all the stuff. Remember to set the segue identifier.
[self performSegueWithIdentifier:#"pushLoginViewController" sender:self]; //Segue needs to exist and to be linked with the performing controller. Only use this if you need to trigger the segue with coder rather than an interface object.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"pushLiftDetail"]) {
[[segue.destinationViewController someMethod:]];
segue.destinationViewController.someProperty = x;
}
}
I think you'll need to add a UITabBar to the modal view and implement/duplicate the buttons and functionality that your main bar has. The essence of a modal window is it has total control until it is dismissed.
You might try putting your UITabBarController into a NavBarController, but I'm not certain that this will work.
UITabBarController -> NavBarController -> Modal View
I have an aplication which initially there's a TabBarController, each tab is a ViewController and every one has a button which calls other controllers.
So how am I supose to structure this? Having one main rootviewController (if so, how?)? Or calling in the appdelegate only the tabBarController and in each the viewControllers inside the tab call the other controllers?
What's the best way so I can advance, go back and transition views nimbly?
Don't know if I made myself clear...
Thanks guys.
Generally you will start with the Template called "Tab Bar Application" and as of Xcode 4 starts by loading the MainWindow Nib, which hold a tab bar and the tab bar is set up in IB to have 2 view controllers, called "FirstViewController", and "SecondViewController"...
You can follow that pattern if it suites you, otherwise you may want to start with a view based application and add your own tab bar. I personally find it to be easier to control the tab bar, through the UITabBarDelegate, especially if you plan to do anything slightly esoteric.
Edit:
Basically one of two ways, if you plan to load a Navigation controller stack, or a single modal view.
1)
ThirdViewController * controller = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
UINavigationController * myNavigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentModalViewController:myNavigationController animated:YES];
[controller release];
[myNavigationController release];
2)
ThirdViewController * controller = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
[self presentModalViewController:controller animated:YES];
[controller release];
either way get back to the Tab environment by calling the following on the view controller that is calling present modal.
[self
dismissModalViewControllerAnimated:YES];