可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have 2 view controllers presented modally.
A presents B which presents C.
When I dismiss C I would like to dismiss B as well. But I am not sure how to do this:
Dismiss C:
[self dismissModalViewControllerAnimated:YES]
//[delegate dismissB] //this doesn't work either when i create a delegate pattern
Now I am left with B. How can I dismiss B from C?
回答1:
Try using the next code in B (right after dismissing C, as you already do):
[self.parentViewController dismissModalViewControllerAnimated:YES];
IMPORTANT:
Don't do anything in the method after this line.
This view controller (B) probably will be released and deallocated...
UPDATE:
Starting from iOS7 the method above is deprecated.
Use the next method instead:
[self.parentViewController dismissViewControllerAnimated:YES completion:^{ /* do something when the animation is completed */ }];
回答2:
Just found out you need to use presentingViewController in iOS 5.
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];
A -> B -> C
Running the above code in modal C will take you back to A
回答3:
This worked for me, very simple
// Call inside View controller C
self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Explanation:
If you call dismiss on C, it can only remove C. If you call dismiss on B, it will do the right thing: Remove the topmost modal view controller. The first call therefore removes C (with no animation). The second call removes B.
The easiest way to access view controller B from C is to use the presentingViewController variable.
回答4:
In B. Put:
[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];
Only run one animation.
回答5:
Check this for swift:
self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil);
回答6:
In swift 4
self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil);
回答7:
You only need one dismiss command. Just dismiss B, and then C will go away with it.
回答8:
I read all the topics and I didn't find a proper answer. If you dismiss B, than C will immediately disappear and create a weird effect. The proper way is to present C as a child view controller with custom animation from the bottom, like:
[b addChildViewController:c];
c.view.frame = CGRectOffset(b.view.bounds, 0, b.view.bounds.size.height);
[b.view addSubview:c.view];
[c didMoveToParentViewController:b];
[UIView animateWithDuration:0.5 animations:^{
c.view.frame = CGRectOffset(c.view.frame, 0, -b.view.bounds.size.height);
} completion:^(BOOL finished) {
}];
And then you simply dismiss B and it all looks much nicer!
回答9:
This worked for me:
// Swift
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
// Objective-C
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
回答10:
The navigation controller has a "viewControllers" property that is an array - you can set that to a new array minus the two view controllers you want to remove.
回答11:
Inspired by Albertos solution, I created a delegate method in B with a block to show a result of deleting an account:
#pragma - mark - AddAccountViewControllerDelegate Methods
- (void) dismissToSettings {
[self dismissModalViewControllerAnimated:NO];
[self dismissViewControllerAnimated:YES completion:^(void){[DKMessage showMessage:LS(@"Account was successfully created")];}];
}
回答12:
I faced the same problem, and a better solution was creating a "DismissViewProtocol" as follow:
File: DismissViewProtocol.h
@protocol DismissViewProtocol <NSObject>
-(void)dismissView:(id)sender;
@end
In my B-modal view, let's response for the delegate method:
in my b.h file:
#import "DismissViewProtocol.h"
@interface B-Modal : UIViewController <DismissViewProtocol>
...
@end
in my b.m file:
-(void) dismissView:(id)sender
{
[((UIViewController *) sender) dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];
}
In the same B-view controller, when I call the
Next, in my B modal view, when I call the other modal view C, supposing that for segue:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
((C-ViewController *)segue.destinationViewController).viewDelegate=self;
}
Finally, in my c.h file, lets prepare for the delegate:
@property(nonatomic, weak) id <DismissViewProtocol> viewDelegate;
And in my c.m file, I just tell my viewDelegate to dismiss my modal view controller and itself:
-(void)closeBothViewControls
{
[self.viewDelegate dismissView:self];
}
And that's it.
Hope it works for all of you.
回答13:
Here is a way how to dismiss more that one modal view controller using repeat cycle:
Swift 3
// In this example code will go throw all presenting view controllers and
// when finds it then dismisses all modals.
var splitViewController: UIViewController? = self
repeat {
splitViewController = splitViewController?.presentingViewController
} while (!(splitViewController is UISplitViewController) && (splitViewController != nil))
splitViewController?.dismiss(animated: true, completion: nil)