如何连续关闭2个模态视图控制器?

问题描述 投票:37回答:14

我有2个视图控制器以模态方式呈现。

A presents B which presents C.

当我解雇C时,我也想解雇B.但我不知道该怎么做:

解雇C:

[self dismissModalViewControllerAnimated:YES]
//[delegate dismissB] //this doesn't work either when i create a delegate pattern

现在我离开了B.如何从C中解雇B?

iphone objective-c cocoa-touch uikit uiviewcontroller
14个回答
9
投票

尝试使用B中的下一个代码(在解雇C之后,就像你已经做的那样):

[self.parentViewController dismissModalViewControllerAnimated:YES];

重要: 在此行之后的方法中不要做任何事情。 这个视图控制器(B)可能会被释放并解除分配......

更新: 从iOS7开始,不推荐使用上述方法。 请改用下一个方法:

[self.parentViewController dismissViewControllerAnimated:YES completion:^{ /* do something when the animation is completed */ }];

0
投票

导航控制器有一个“viewControllers”属性,它是一个数组 - 您可以将其设置为新数组减去要删除的两个视图控制器。


0
投票

受Albertos解决方案的启发,我在B中创建了一个委托方法,其中有一个块来显示删除帐户的结果:

#pragma - mark - AddAccountViewControllerDelegate Methods

- (void) dismissToSettings {
    [self dismissModalViewControllerAnimated:NO];
    [self dismissViewControllerAnimated:YES completion:^(void){[DKMessage showMessage:LS(@"Account was successfully created")];}];
}

0
投票

我遇到了同样的问题,更好的解决方案是创建一个“DismissViewProtocol”,如下所示:

文件:DismissViewProtocol.h

@protocol DismissViewProtocol <NSObject>
-(void)dismissView:(id)sender;
@end

在我的B模式视图中,让我们对委托方法做出响应:

在我的b.h文件中:

#import "DismissViewProtocol.h"
@interface B-Modal : UIViewController <DismissViewProtocol>
...
@end

在我的b.m文件中:

-(void) dismissView:(id)sender
{
 [((UIViewController *) sender) dismissModalViewControllerAnimated:NO];
 [self dismissModalViewControllerAnimated:YES];
}

在同一个B视图控制器中,当我调用Next时,在我的B模态视图中,当我调用另一个模态视图C时,假设对于segue:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    ((C-ViewController *)segue.destinationViewController).viewDelegate=self;
}

最后,在我的c.h文件中,让我们为代理做准备:

@property(nonatomic, weak) id <DismissViewProtocol> viewDelegate;

在我的c.m文件中,我只是告诉我的viewDelegate解除我的模态视图控制器及其自身:

-(void)closeBothViewControls
{
       [self.viewDelegate dismissView:self];
}

就是这样。

希望它适用于所有人。


0
投票

这是一种如何使用重复循环忽略一个模态视图控制器的方法:

斯威夫特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)

0
投票

我知道这个答案可能会多余,但下面的陈述应该是有道理的,你会知道它是如何工作的。

只需关闭最旧的视图控制器,所有其他后来的视图控制器都会消失。

如果是2个视图控制器:

目标C:

[self.presentingViewController dismissViewControllerAnimated:true completion:nil]

迅速:

presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

0
投票

我找到了解决方案。

你可以将这些ViewControllers放在一个单独的NavigationController中。并且解雇NavigationController将导致所有这些ViewControllers立即解雇。

https://gist.github.com/ufo22940268/2949fdf59c9860292f263ebb1e8036d7


109
投票

刚刚发现你需要在iOS 5中使用presentViewController。

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];

A - > B - > C.

在模态C中运行上面的代码将带您回到A.


14
投票

这对我有用,非常简单

// Call inside View controller C    
self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

说明:

如果你在C上调用dismiss,它只能删除C.如果你在B上调用dismiss,它会做正确的事:删除最顶层的模态视图控制器。因此第一个调用删除C(没有动画)。第二次调用删除B.

从C访问视图控制器B的最简单方法是使用presentsViewController变量。


12
投票

在B. Put:

[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];

只运行一个动画。


6
投票

检查这是否为swift:

self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil);

4
投票

在快速4

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil);


2
投票

您只需要一个解雇命令。只要解雇B,然后C就会消失。


2
投票

我阅读了所有主题,但没有找到合适的答案。如果你解雇B,那么C会立即消失并产生一种奇怪的效果。正确的方法是将C作为子视图控制器从底部呈现自定义动画,如:

   [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) {

    }];

然后你只是解雇B而且它看起来都更好!


2
投票

这对我有用:

// Swift
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

// Objective-C
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
© www.soinside.com 2019 - 2024. All rights reserved.