Displaying a ViewController from a TabView modally - objective-c

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.

Related

How to access Tab View Controller from another View Controller

I'm having trouble accessing my view controllers under the tab bar controller. Here is what my storyboard looks like:
View Controller A (-> Page View Controller -> View Controller C
View Controller A -> Tab Bar Controller (MyTabBarController.h/.m) -> Navigation Controller (MyNavigationController.h/.m)-> View Controller B (TabViewController.h/.m)
Tab Bar Controller (MyTabBarController.h/.m) -> View Controller D
Tab Bar Controller (MyTabBarController.h/.m) -> View Controller E
From View Controller A I have an IBAction called loginButton that is connected to the Tab Bar Controller, and currently it looks like this:
- (IBAction)loginButton:(id)sender {
MyNavigationController *localNavigationController;
UIStoryboard * storyboard = self.storyboard;
MyTabBarController *tbc = [[MyTabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:1];
TabViewController *login = [storyboard instantiateViewControllerWithIdentifier: # "TabViewController"];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:login];
localNavigationController.delegate = self;
[localControllersArray addObject:localNavigationController];
tbc.viewControllers = localControllersArray;
tbc.delegate = self;
tbc.moreNavigationController.delegate = self;
tbc.selectedIndex = 0;
[self presentViewController:tbc animated:YES completion:^{
}];
}
I'm not able to get this displayed correctly. I am getting a bunch of warnings in this piece of code. and it is also not showing the different tab items in the bottom of the Tab Bar, even though I have put images/text on each tab.
So how do I display/access the view controllers inside the Tab Bar Controller correctly? (ie View Controllers C/D/E)?
The storyboard that you show in your question already contains the tab bar controller, navigation controller, and login controller properly hooked up to each other. Because of that, you shouldn't be instantiating a new tab bar controller or navigation controller in code -- they will be instantiated by the storyboard when you instantiate the tab bar controller. So, the only thing you need to do, is to give the tab bar controller in the storyboard an identifier, and do this (assume the identifier is called MyTabBarController):
- (IBAction)loginButton:(id)sender {
UITabBarController *tbc = [self.storyboard instantiateViewControllerWithIdentifier:#"MyTabBarController"];
[self presentViewController:tbc animated:YES completion:nil];
}
You wouldn't even need this code if you control drag from the "Login" button to the tab bar controller, and choose "Modal". That will create a modal segue which will present the tab bar controller with no code at all.
If you just want to select another tab from the tabBar controller then use something like this:
UITabBarController *tabBar = (UITabBarController *)self.window.rootViewController;
[tabBar setSelectedIndex:3];
Note that if the tabBar controller is the initial view controller you can grab an instance of it it the applicationDidFinishLaunching method and store it in the AppDelegate. Then you'll be able to access it like this:
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Remember to import the AppDelegate.h
I recommand you to use a Singleton shared instance to share multiple informations form multiple controllers.
It's a good design Pattern for you usage.
I'm writing samples of Design Patterns usage on cocoa (see https://github.com/leverdeterre/DesignPatterns -> Real singleton)

Present viewController from AppDelegate using UITabBarController design

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.

How to presentModalViewController without dismiss the TabBarController

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

iOS: Trying to add Navigation Bar to Modal UITableViewController

I'm following the CoreDataRecipes app for modaly showing the add screen when I want to add a new item. However I cannot get the bar to display at the top so I can press 'Done' or 'Cancel'.
In the xib calling the modal controller I have the + button linked to modally sliding up the controller via IB.
I have the below in my modal controller
self.navigationItem.title = #"Add";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:self action:#selector(save)];
self.navigationController.navigationBarHidden = NO;
In my viewDidLoad
The modal controller displays fine except there is no bar so I cannot leave that screen.
You need to add it before the popover is actually presented.
Where you create the modal popover, you need to create it inside a UINavigationController first.
So, do the following.
PopoverView *foo = [[PopoverView alloc] initWithNibName:#"PopoverView" bundle:nil];
// Here you pass through properties if you need too.
// ...
UINavigationController *navC = [[UINavigationController alloc] initWithRootView:foo];
[foo release];
[self.navigationController presentModalViewController:navC animated:YES];
That will give the modal view the navigation bar which you're trying to edit.
Alternatively, you could maintain your storyboard segue. In Xcode, select the view controller you are trying to transition to and embed it in a navigation controller.
Now in the viewDidLoad of that view controller, add:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
and lastly the callback:
- (void)cancel {
[self dismissModalViewControllerAnimated:YES];
}
Or if you just need the look of the bar, not exactly its functionality, you could drag the Navigation Bar (UINavigationBar) or Toolbar (UIToolbar) controll from the Media Library panel onto your view and go from there.
I had a similar predicament whereby I was loading a UITableViewController in a containerView. The containerView was inside a UIViewController which was being presented in a modal fashion.
I, like you, needed the navigation bar to have a title and a Done/Cancel button.
After overflowing the stack, I finally did this -
Dragged a UIView as the first item in the Table View in the IB. This automatically took a height of 44 pts and snapped to the top. It also shifted my first section downwards.
I dragged a UIButton (Done button) inside this view. Created an IBOutlet to it and called
[self dismissViewControllerAnimated:YES completion:nil];
Disclaimer:
1) This fake nav-bar will scroll along with the tableview.
2) This might not be a solution for what Bot has asked, but it's an option for others who might be looking for something similar.

UIView transitions present modal view at the bottom

I need to display a UIView/UIViewController when the user taps a button and the modal view should appear just like how the key board appears from the bottom bar when you edit text in a UITextField. Using the following code, I get to show it as a pop up.
[self presentModalViewController:child animated:YES];
How to make it appear like the keyboard?
I understad modal views cover the entire screen. But I really want a view that covers only half the screen. So, please tell me why this doesn't work
MyController *controller = [[MyController alloc] initWithNibName:#"MyView" bundle:nil];
CGRect frame = CGRectMake(0,44,768,264);
[controller view].frame = frame;
contoller.delegate = self;
[[self view] addSubView:[controller view]];
[controller release];
I am trying to add a sub view to my current view and make it appear where the keyboard appears.
Check if your child.modalTransitionStyle == UIModalTransitionStyleCoverVertical.
(And a model view controller always cover the whole screen. If you just need to cover half of the screen like the keyboard, you need to put the view controller's view as a subview of the main view, then animate it in manually with animation blocks.)
I know its an old question, but an answer to this is to use a UIActionSheet.
It won't present a View Controller, but you can present custom views that only cover a portion of the screen.
Check out this question for more information
Add UIPickerView & a Button in Action sheet - How?