I'm updating an iOS app and receiving the following warning when presenting a view controller: Presenting view controllers on detached view controllers is discouraged <UINavigationController: 0x984e640>.
The app delegate loads the main view controller like this:
[self.window setRootViewController:[MainViewController sharedInstance]];
[[MainViewController navigationController]setViewControllers:#[[MenuViewController new]]];
MainViewController creates a new navigation controller and in viewDidLoad the new navigation controller is added to the view with this:
[self.view addSubview:_navigationController.view];
Now I need to present another view controller. I have tried using this:
[_navigationController presentViewController:anotherViewController animated:YES completion:nil];
and this:
[[MainViewController navigationController] presentViewController:anotherViewController animated:YES completion:nil];
+ (UINavigationController*)navigationController {
return [[MainViewController sharedInstance]navigationController];
}
I get the same warning with both of them and the view controller loads, but I cannot navigate back. I'm obviously doing something wrong, but I'm not sure what it is.
I think you want to push it instead of modally present it : presentViewController is a method from UIViewController to present modal VCs, whereas pushViewController pushes VCs in the navigation stack.
Try this instead :
[_navigationController pushViewController:anotherViewController animated:YES];
Related
I need to present a UIViewController as fullscreen (Above all other views). This UIViewController is currently inside a UINavigationController.
Is it possible to have the UINavigationController present it's current top UIViewController modally?
From within the UIViewController I would like to fullscreen, if I use:
[self.navigationController presentViewController:self animated:YES completion:nil]
Nothing seems to happen.. Is there a reason this is not allowed?
EDIT
I have posted another question in which I have solved this issue for every scenario. (Code snippet included there)
Is it possible for a UIViewController to present itself?
If you want to present a view controller modally, you should be presenting it from a different view controller. The modal presentation will show the presented view controller over the navigation controller (in fullscreen)
For instance,
UIViewController *firstVC = self;
UIViewController *secondVC = <the VC you want to present>
[firstVC presentViewController:secondVC animated:YES completion:nil]
Or just use a modal segue in Interface Builder.
You should use this :
[self presentViewController:self.navigationController animated:YES completion:nil];
to show a controller.
Assuming that the view controller you want to show modally is the navigation controllers top view controller
[self presentViewController:self.navigationController.topviewcontroller animated:YES completion:nil];
Hope this helps
I have tab bar based application (iOS 7.1 SDK). When user start app at first time, I want show some login screen. I decided to use view controller containment (this is called in first view controller of tab bar controller):
LoginViewController *vc = [LoginViewController new];
[self.tabBarController addChildViewController:vc];
[vc didMoveToParentViewController:self.tabBarController];
[self.tabBarController.view addSubview:vc.view];
But there are some problems. View is normally visible, but in LoginViewController viewWillAppear and viewDidAppear are never called. I try to use this piece of code in all view lifecycle methods (viewDidLoad, viewWillAppear, viewDidAppear), but with no luck. I know there are some other ways to achieve what i'm trying to do. For example add child controller to first view controller of tab bar controller and hide tab bar, which works great and viewWillAppear and viewDidAppear are normally called. But because of this I get even more curious - why adding child view controller to tab bar controller don't work as expected?
You need to present or push the viewcontroller in order for the methods to get called. Just adding the view as a subview will not work.
In your case, you can explicitly call the viewWillAppear, viewDidAppear methods.
LoginViewController *vc = [LoginViewController new];
[self.tabBarController addChildViewController:vc];
[vc didMoveToParentViewController:self.tabBarController];
[self.tabBarController.view addSubview:vc.view];
[vc viewWillAppear];
[vc viewDidAppear];
It's working!
dispatch_async(dispatch_get_main_queue(), ^{
[self.tabBarController setSelectedIndex:0];
[self.tabBarController setSelectedIndex:1];
[self.tabBarController setSelectedIndex:0];
});
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];
}
I have a view controller B in a parent view controller A. Both views are showing the same time.
In view controller B, I'm trying to present a new view controller using the following method:
- (void) buttonClicked:(id)sender
{
MyViewcontroller *vc = [[MyViewcontroller alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
The view controller appears correctly in iOS6 and I dismiss MyViewController by using the following method:
- (IBAction)backButtonPressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
But there is a difference between iOS 5.1 and iOS 6.
QN1: Upon dismissal, view controller A & B viewDidAppear are not invoked. Is it supposed to be triggered?
QN2: I can't get MyViewController to show up in iOS 5.1.1. unless I add view controller B as a child container to A:
[self addChildViewController:vcB];
[self.view addSubview:vcB.view];
By adding the child controller, I can get MyViewController to show and view controller A&B viewDidAppear will be called when it gets dismissed. viewDidAppear also gets called when using iOS6.
I'm not sure what is going on here.
Answer 1 : viewDidAppear will not be called when you dismiss a modal view.
Answer 2 : if you are presenting "MyViewController" from "View-controller B" then View-controller B's view should be in view hierarchy.
From here you can get more information. How to Presenting View Controllers from Other View Controllers
I'm trying to get working a simple operation. At least it seems simple. Ok, what I'd like to do is to push a view (with push view controller) from a view that has been pushed with modal view controller.
View1 --(push using modal view controller)-->View2--(push using push view controller)--View3.
Rigth now, i'm doing tests so i'm using a button to start the action. Here's the code I use to push from View2 to view 3:
//view2.h
UIToolbar *bar;
UIBarButtonItem *button;
UIToolbar *toolbar;
}
- (IBAction)demissModal:(id)sender;
- (IBAction)goView3:(id)sender;
#end
//view2.m
- (IBAction)goView3:(id)sender{
View3 *view_3 = [[View3 alloc] initWithNibName:#"View3" bundle:nil];
[self.navigationController pushViewController:view_3 animated:YES];
}
This is the same code I use to push View1 to View2, and it works. But when pushing View2 to View3, it's not working. Any idea of why happens that? Thanks!
View Controllers aren't actually 'modal' or 'push' view controllers. Modal or Push describe a transition between view controllers (called segues if you're using storyboards).
What I think you're asking is how to modally present a view controller, and then push another controller. The trick is when you modally present view controller #1, to actually present a navigation controller with its root view controller set as view controller #1.
MyViewController *myViewController = [MyViewController alloc] init];
UINavigationController *navController = [UINavigationController alloc] initWithRootViewController:myViewController];
// Presuming a view controller is asking for the modal transition in the first place.
[self presentViewController:navController animated:YES completion:nil];
// Now in myViewController, call [self.navigationController pushViewController:secondViewController animated:YES];
This is what it looks like using storyboards:
First of all, I'm not sure where that gegant_se is coming from.
Second of all, if you're pushing view2 from view1 the same way you're pushing view3 from view2, you're not using a modal.
Whenever you use a navigation controller to push a view controller, that view controller that was just pushed has a reference to the navigation controller, through the navigationController property. Try this:
[self.navigationController pushViewController:view_3 animated:YES];
Try this:
[self.navigationController pushViewController:view_3 animated:YES];
try this code AlarmList is view name .
AlarmListScreen *loscr=[[AlarmListScreen alloc]initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:loscr animated:YES];
[loscr release];