on viewdidload of one of my tabbar viewcontrollers I'll like to display or popup another view controller. here's my code
if (_history.count == 0) {
//[self performSegueWithIdentifier:#"emptyHistorySegue" sender:self];
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MSAEmptyHistoryViewController *popupController = [sb instantiateViewControllerWithIdentifier:#"EmptyHistoryViewController"];
[self presentViewController:popupController animated:NO completion:nil];
}
The load the viewcontroller on top of the tabview controller. I need this view to display but still allow the user to see the tabbar buttons.
You will run into problems if you try to transition to another view controller in viewDidLoad. You should either switch the child view controllers of the tab bar controller or you can present a subview within one of the child view controllers.
When -viewDidLoad is called, the view controller is generally not presented. As such, if you try to present another controller, it will crash.
Try -viewDidAppear: if you want what you are describing.
Related
There is problem in view hierarchy. Here is flow of my app.
When app starts View Controller "A" is Visible. After that storyboard "B" is loaded through "StoryBoard Reference (Push)" ,Where another navigation controller is present and Home screen is loaded. On Click of Menu button in Home screen Side panel is visible.
Now When i click on side panel menu items view Controller "B" is pushed. This View Controller is Pushed Under Home screen and is not Vsible.
Help View contoller is visible under Home controller. I want Help View Controller should come on top of Home controller.
I dont understand what issue is coming..
Any Help will be appreciated..
If you are pushing view controller from side panel shows in image, will never push because it is not in navigation controller.
the answer depends on how you showing your side menu but from assumptions
what you need to do is to set root view controller or keep reference of navigation controller and push from there
If you are presenting side menu then it is not on navigation controller so you should first dismiss this side menu and on the completion of it you should push new view controller (says B or Help). I am writing my code snippet that i am using in my project for demonstration,
- (IBAction)settingClick:(id)sender {
SettingViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:#"settingsScreen"];
[self dismissViewControllerAnimated:NO completion:^{
[self.vc.navigationController.navigationController pushViewController:svc animated:YES];
}];
}
Above method push setting view controller on current navigation controller after dismissing side menu
Now important thing is self.vc this is the object of previous viewcontroller (Home controller in your case i think) on which side menu was presented.
So my SideMenuViewController has a property like,
#property (nonatomic,strong) UIViewController *vc;
which i am setting with self from previous view controller (in your case from Home view controller) something like,
SideMenuViewController *smvc = [self.storyboard instantiateViewControllerWithIdentifier:#"sideMenu"];
smvc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:smvc animated:NO completion:^{
smvc.vc = self;
}];
And i have used [self.vc.navigationController.navigationController pushViewController:svc animated:YES]; i.e. two navigation controller to push because i have two navigation controller in my view hierarchy to push this new view controller.
You can manage that as per your setup that how many navigation controller you have !!
Hope this will help :)
After digging a lot, I found solution for this.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Home" bundle: nil];
RootController *someViewController = [storyboard instantiateViewControllerWithIdentifier:#"RootController"];
[self.navigationController pushViewController:someViewController animated:YES];
I have set another navigation controller as root ViewController of the window and it worked for me.
Thanks.
I added a Navigation Controller to my storyboard and it appears like so:
Now in the table view controller, I gave the TableViewController a storyboard id and class to a TableViewController Controller
When I run my app, I don't see the Navigation Bar at the top. This has been extremely frustrating and can't find a solution anywhere. PLEASE HELP
To get to the scene, someone clicks a button and this code runs and it goes to my Table View Controller:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
LHFileBrowser *LHFileBrowser = [storyBoard instantiateViewControllerWithIdentifier:#"FileBrowser"];
[self.navigationController pushViewController:LHFileBrowser animated:YES];
[self presentViewController:LHFileBrowser animated:YES completion:nil];
The error is in your code.
If you want to (modally) present a view controller when the user presses a button, you need to present the navigation controller (which will contain the table view controller), not the table view controller itself.
Right now, you're presenting the view controller, which won't show it being embedded in a navigation controller.
Also, you're mixing up two different approaches, by trying to push a view controller onto a navigation controller stack, and also presenting the view controller.
Code Sample:
Here's what you apparently mean to do:
UIStoryboard *storyboard = self.storyboard;
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"MyNavigationControllerID"];
LHFileBrowser *rootViewController = [navigationController topViewController];
// Configure your LHFileBrowser view controller here.
rootViewController.someProperty = ...;
// Modally present the embedded view controller
[self presentViewController:navigationController animated:YES completion:nil];
If you want to change the presentation or transition style, you can set those details in your storyboard.
You didn't explain why you had to programmatically add buttons, but Storyboard segues would have instantiated and presented an embedded view controller for you, without you having to have done it in code.
The more you can do in Storyboard, the less code you have to maintain, support, and update, and the more likely your app will still work properly when a new SDK is released.
Update:
The better way to do this is to let Storyboard do it for you, by adding a segue from the button to the navigation controller that you want to present.
I would like to have my application have custom buttons in the CameraViewController; one pushes to Rustles ViewController (Top VC in photo below) and the other transitions to ViewController (Bottom VC).
Right now my application can properly segue to the viewControllers by using the following method:
-(void)segueToRustlesTableViewController{
if (debug==1) {NSLog(#"Running %# '%#'", self.class, NSStringFromSelector(_cmd));} // simple debug statement, can ignore
// Instantiate nav controller which segues to table view
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil]; // must assume only IPhone
RustlesTableViewController *rustlesTVC = (RustlesTableViewController *)[storyboard instantiateViewControllerWithIdentifier:#"RustlesView"];
[self performSegueWithIdentifier:#"tableSegue" sender:self];
[self.PickerController presentViewController:rustlesTVC animated:NO completion:nil];
}
However when I get to the UIViewControllers I can't transition back to the old UIViewControllers, presumably because I have no Navigation Controllers embedded in each UIViewControllers.
My code right now wouldn't work for a NavigationController but I don't really know how to transition to the NavigationController and then the UIViewControllers after the Navigation Controller.
How do I transition from CameraViewController to aNavigationController and then to the RustlesViewController?
If you aren't making use of a navigation controller, I would make a custom button in the spawned view controller (Rustles, View) and call
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
I believe this should work.
I have a storyboard in my application with a navigation controller and several views. This automatically puts a navigation bar with a back button into any views that are not the root view.
However, sometimes I navigate away from this storyboard to an individual nib. I want to navigate back to the storyboard, but not necessarily to the original root view. I currently use this method to do so:
+(void) TransitionOnStoryboard:(NSString*)storyboard to:(NSString*)identifier withViewController:(UIViewController*)viewController
{
UIStoryboard *sb = [UIStoryboard storyboardWithName:storyboard bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:identifier];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[viewController presentViewController:vc animated:YES completion:NULL];
}
This shows the view I want but without the navigation bar. How do I specify my navigation controller or root view, such that the app knows to put a navigation bar with a back button in?
Thanks
The answer is to leave your navigation controller underneath the view controller you add from a nib.
Present the nib as a full0-screen modal. That gets rid if your navigation bar, as desired. From that new view controller, you can push more modals, add a navigation controller, or whatever.
Note that you could do all of this and stay inside your storyboard as well.
Once you are done, dismiss the modal to reveal your navigation controller, and you are back in business with your storyboard. You can push a new view controller onto your navigation controller without animation and it should appear as the front-most VC when you pop the modal that came from a nib.
I'm sure that this isn't the ideal way to solve this problem, but it did work very nicely for me.
Essentially, I removed all the views from the view controller that had been generated since I navigated away from the storyboard, but before the current view and popped the current view. In this case, these views were of one class (CheckboxListViewController) and so could be removed quite simply as below:
+(void) navigateToMainMenu:(UINavigationController*)navigationController
{
[QuickView removeFromNavigationController:navigationController allOfViewControllerWithClass:[CheckboxListViewController class]];
[navigationController popViewControllerAnimated:YES];
}
+(void) removeFromNavigationController:(UINavigationController *)navigationController allOfViewControllerWithClass:(Class)viewControllerClass
{
NSMutableArray *keptViewControllers = [[NSMutableArray alloc]init];
for (UIViewController *viewController in navigationController.viewControllers)
if (![viewController isKindOfClass:viewControllerClass])
[keptViewControllers addObject:viewController];
navigationController.viewControllers = keptViewControllers;
}
(note- QuickView is the name of the class that contains these methods.).
Any other classes that you do not want your pop to navigate back to can be removed by calling:
[QuickView removeFromNavigationController:navigationController allOfViewControllerWithClass:[YourClassName class]];
In the navigateToMenu method.
In all view controllers I present a ModalViewController after I dismiss modal view controller I want to call a method in current view controller.
I have to presentModalViewController I cant push it because it is a form sheet. Since I cant push it (void)viewDidAppear:(BOOL)animated is not called when I dismiss the form sheet.
Btw form sheet is a settings menu and I have to call it in every view controller, so I cant use notifications because there are over 20 View controllers and only one settings menu;
Navigation controller -> Root- > VC1 - > VC2 - > VC3 ->VC4........... VC20......
| | | | |
Menu Menu Menu Menu Menu
I present menu:
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:nil];
SettingsListViewController *settingsVC = [sb instantiateViewControllerWithIdentifier:#"SettingsListViewController"];
UINavigationController *modalViewNavController= [[UINavigationController alloc] initWithRootViewController:settingsVC];
modalViewNavController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
modalViewNavController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:modalViewNavController animated:YES];
I dismiss it :
//dissmiss view
[self.navigationController dismissModalViewControllerAnimated:YES] ;
In View Controllers I want to Call;
[self.navigationController popToRootViewControllerAnimated:NO];
Is there a way to call a method in View Controller when form sheet is dismissed ?
Since iOS 5, you can use the presentingViewController property of every UIViewController to see 1) if they're being presented modally in the first place and 2) who it is that's presenting them modally then. So if you present your form sheet by calling [self.navigationController presentModalViewController:modalViewNavController animated:YES], the presenting view controller will then be the root navigation controller and you can tell it to pop to root at the same time you dismiss the modal presentation.
By the way, there's also a storyboard property in every view controller which has originated from a storyboard, so you could use that one directly when instantiating new storyboard view controllers by name.
Make your own delegate and set the view controller that presents the view as delegate.. and call from modalVC when it is about to be dismissed.
You can set modalViewController.parentViewController = self; and then work with it from modal view controller like that if you want to send messages before dismiss:
- (void)viewWillDisappear:(BOOL)animated {
[self.parentViewController doSomething];
}