On my project we have three windows A, B and C. From A I would like to push view B, and from B I would like to present view C.
My code:
ViewController A:
ViewControllerB *vcB = [[viewControllerB alloc]
initWithNibName:#"ViewControllerB" bundle:nil];
[[self navigationController] pushViewController:vcB animated:YES];
View Controller B:
ViewControllerC *vcC = [[ViewControllerC alloc]
initWithNibName:#"ViewControllerC" bundle:nil];
[self presentViewController:vcC animated: true completion: nil];
Everything is ok until now, but when I dismiss the last view controller with:
[[self presentingViewController] dismissViewControllerAnimated:NO completion:nil];
The app goes back to first view controller (vcA) instead the second one (vcB)
What am I doing wrong?
Thank you, guys.
You must be doing something else that you're not telling us about...
This works as expected:
In MyFirstViewController.m
- (IBAction)pushTapped:(id)sender {
MyPushedViewController *vc = [[MyPushedViewController alloc] initWithNibName:#"MyPushedViewController" bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
}
In MyPushedViewController.m
- (IBAction)presentTapped:(id)sender {
MyPresentedViewController *vc = [[MyPresentedViewController alloc] initWithNibName:#"MyPresentedViewController" bundle:nil];
[self presentViewController:vc animated:YES completion:nil];
}
In MyPresentedViewController.m
- (IBAction)dismissTapped:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
}
Tapping the "dismiss" button in MyPresentedViewController dismisses the presented view controller (your vcC), leaving me at MyPushedViewController (your vcB) ... NOT at MyFirstViewController (your vcA).
try this to dismiss vc
[self dismissViewControllerAnimated:NO completion:nil]
and use this to pop
[self.navigationController popToViewController:controller animated:YES];
[self presentingViewController] = Bvc , so here you actually dismissing B not C
[Bvc dismissViewControllerAnimated:NO completion:nil];
but self = Cvc so here you dismissing C only
[self dismissViewControllerAnimated:NO completion:nil];
Related
I have a UIViewControllerC which is call from two another UIViewcontroller
ViewControllerA
ViewControllerB
From ViewControllerA to go to UIViewControllerC i have to make it presentviewcontroller
UIViewControllerC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"UIViewControllerC"];
[vc setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
vc.tagfrom=#"present";
[self presentViewController:vc animated:NO completion:nil];
From ViewControllerB to go to UIViewControllerC i have to make it push view
UIViewControllerC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"UIViewControllerC"];
[vc setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
vc.tagfrom=#"push";
[self.navigationController pushViewController:vc animated:YES];
Now i have to back from both view on back button i check tagfrom condition and handle it
-(IBAction)backBtn:(id)sender
{
if ([tagfrom isEqualToString:#"present"])
{
[self dismissViewControllerAnimated:NO completion:nil];
}
else
{
[self.navigationController popViewControllerAnimated:YES];
}
}
Which working fine in both senerio, but sometimes my push view behaves like presentmodelveiw, and having no transition effects in it, please help me to resolve it
First of all, you don't need tagfrom property on your UIViewController subclass.
A UIViewController instance has a property called presentingViewController which will let you know about the viewController ( A in your case ) that presented current viewController ( C in your case ).
-(IBAction)backBtn:(id)sender
{
if (nil != self.presentingViewController) {
[self dismissViewControllerAnimated:NO completion:nil];
}
else {
[self.navigationController popViewControllerAnimated:YES];
}
}
Second, modalTransitionStyle is supposed to work with only presentation and NOT push / pop transitions. If you are using this with push / pop, the behavior is undefined because it is not meant to be used there.
I have a timer in my app. If the timer reaches 0, the user is brought to a failure page. When that happens, the previous ViewController was not dismissed, leading to more memory being taken up.
I want the previous ViewController to be dismissed if the Failure Page is presented.
if (self.countdownTimer == 0) {
FailurePage *failurePage = [[FailurePage alloc] init];
[self presentViewController:failurePage animated:YES completion:NULL];
//I want to dismiss the current ViewController when the Failure Page is presented
}
You can do something like this:
if (self.countdownTimer == 0) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
FailurePage *failurePage = (FailurePage*)[mainStoryboard instantiateViewControllerWithIdentifier: #"<Controller ID>"];
[self presentViewController:failurePage animated:YES completion:^{
[self.parentViewController dismissViewControllerAnimated:NO completion:nil]
}];
}
I'm doing an ios project without using any story board and xibs.
Here I've come out one problem on presenting my UIViewController.
Here is the senario:
My RootViewController has 2 UIButton's that can present ViewControllerA and ViewControllerB when being pressed.
-(IBAction)btnAclicked:(id)sender{
[self.navigationController presentViewController:ViewControllerA];
}
-(IBAction)btnBclicked:(id)sender{
[self.navigationController presentViewController:ViewControllerB];
}
And now inside ViewControllerA
I have a button to presentViewContollerB as well, and I want only the RootViewController to be displayed when I dismiss ViewContollerB.
In order to do this, I need to dismiss ViewControllerA first then presentViewControllerB. I know there is ways like using delegate to make it works, but I just want to know if there is any easier way to do this.
To be emphasised is that I want to use presentViewController only, not pushViewController. Thanks
I have an answer for your question,just do the following code,
in RootViewController.m
- (IBAction)gotoViewA:(id)sender
{
ViewControllerA *viewControllerA = [[ViewControllerA alloc]initWithNibName:#"ViewControllerA" bundle:nil];
[self presentViewController:viewControllerA animated:YES completion:nil];
}
- (IBAction)gotoViewB:(id)sender
{
ViewControllerB *viewControllerB = [[ViewControllerB alloc]initWithNibName:#"ViewControllerB" bundle:nil];
[self presentViewController:viewControllerB animated:YES completion:nil];
}
in ViewControllerA.m
- (IBAction)actionBackFromA:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
in ViewControllerB.m
- (IBAction)actionBackFromB:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Use the completion block of presentviewcontroller,viz will executed first
[self presentViewController:goTo_B animated:YES completion:^{
//Dismiss A
[self dismissViewControllerAnimated:YES completion:nil];
}];
If this does not work,write dismiss and just after it present your new controller
[self dismissViewControllerAnimated:YES completion:nil];
[self.view.window.rootViewController presentViewController:goTo_B animated:YES completion:^{ }];
There's another way out, but i don't know whether its appropriate or not.
Create a property of type View Controller A in view controller B.
While presenting view controller B, assign an instance of View Controller A to the property in view Controller B.
[self presentViewController:goTo_B animated:YES completion:^{
goTo_B.propertyOfViewControllerA = self;
}];
After that while dismissing view controller B you can do the either of the two:
[self dismissViewControllerAnimated:YES completion:nil];
[propertyOfViewControllerA dismissViewControllerAnimated:YES completion:nil]
or
[self dismissViewControllerAnimated:YES completion:^{
[propertyOfViewControllerA dismissViewControllerAnimated:YES completion:nil]
}];
In MyMainViewController, I present a navigation controller like this:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UINavigationController* nc = [storyboard instantiateViewControllerWithIdentifier:#"NAVIGATION_CONTROLLER_ID"];
[self presentViewController:nc animated:YES completion:nil];
Later, from somewhere within the view hierarchy of the UINavigationController, I need to return to MyMainViewController. How can I do this?
(Note: MyMainViewController is defined in a .XIB, and not in the storyboard where the UINavigationController and it's children are defined.)
It sounds like you have modally presented a NavController that you want to remove. Modally presented VC's can remove themselves.
Somewhere in your NavController add:
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Dismissed nav controller modally");
}]
[self.navigationController popToViewController:[[self.navigationController viewControllers] objectAtIndex:2] animated:YES];
I gues you know the index of your view controller. If you simply want to return to the rootViewController you can do it like
[self.navigationController popToRootViewControllerAnimated:YES];
If you want to push new viewController to the navigation stack just do it like
MyMainViewController *mainController = [[MyMainViewController alloc] initWithNibName:#"MyMainViewController" bundle:nil];
[self.navigationController pushViewController:desController animated:YES];
Returning to the previous viewController would be
[self dismissViewControllerAnimated:YES completion:nil];
Im calling this code from the MasterViewController in a UISplitVC for an iPad app:
-(void)viewWillAppear:(BOOL)animated{
//PRESENT MODALVC
ModalViewController *modalVC = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
[self setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:modalVC animated:YES];
}
but it doesn't work. No ModalVC appears.
Try this code:
ModalViewController *modalVC = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
[modalVC setModalPresentationStyle:UIModalPresentationFullScreen]; //You set the presentation style of the controller that would be presented, not the presenting controller
//This check is needed, because presentModalViewController:animated is depreciated in iOS5.0 and presentViewController:animated:completion must be used instead. The same is valid for dismissModalViewControllerAnimated and dismissViewControllerAnimated:completion
if([self respondsToSelector:#selector(presentViewController:animated:completion:)])
[self presentViewController:modalVC animated:YES completion:nil];
else
[self presentModalViewController:modalVC animated:YES];
If you are targeting iOS5.0+ only this check is not needed and you should use only presentViewController:animated:completion and dismissViewControllerAnimated:completion