关闭堆栈中较低的ViewController不会按预期运行

rdu*_*and 9 objective-c uiviewcontroller ios presentviewcontroller

我正在构建一个复杂的应用程序,中间有一个分支.

在应用程序的某个时刻,会出现一个特定的UIViewController,我们称之为mainViewController(缩短mainVC).

所述mainVC呈现另一视图控制器,通过代码,使用下面的代码(I去掉隐私的原因它的一部分):

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SecondaryStoryboard" bundle:secondaryBundle];
SecondViewController *secondVC = [storyboard instantiateInitialViewController];
[self presentViewController:secondVC animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

因此,secondVC稍后会出现另一个视图控制器,称为thirdVC.这是使用自定义segue完成的,在上面的代码中使用的故事板中设置,代码如下所示:

@implementation VCCustomPushSegue

- (void)perform {

    UIView *sourceView = ((UIViewController *)self.sourceViewController).view;
    UIView *destinationView = ((UIViewController *)self.destinationViewController).view;

    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
    destinationView.center = CGPointMake(sourceView.center.x + sourceView.frame.size.width, destinationView.center.y);

    [window insertSubview:destinationView aboveSubview:sourceView];

    [UIView animateWithDuration:0.4
                     animations:^{
                         destinationView.center = CGPointMake(sourceView.center.x, destinationView.center.y);
                         sourceView.center = CGPointMake(0 - sourceView.center.x, destinationView.center.y);
                     }
                     completion:^(BOOL finished){

                         [self.sourceViewController presentViewController:self.destinationViewController animated:NO completion:nil];
                     }];

}

@end
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这个segue通过presentViewController:自定义动画(从右到左的幻灯片)以模态方式(通过使用)呈现目标视图控制器.

所以基本上到这里一切都很好.我展示了secondVC一个经典的模态动画(从底部向上滑动)并呈现thirdVC我的自定义过渡.

但是当我想解雇时thirdVC,我想要的是直接回到mainVC.所以我打电话给以下人员thirdVC:

self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:_animate completion:nil];
Run Code Online (Sandbox Code Playgroud)

那样的话,我dismissViewControllerAnimated:直接打电话mainVC(引用self.presentingViewController.presentingViewController),我期待着thirdVC被动画解雇,并且secondVC只是在没有动画的情况下消失.

正如Apple在UIViewController类文档中所说:

呈现视图控制器负责解除它所呈现的视图控制器.如果在呈现的视图控制器本身上调用此方法,它会自动将消息转发给呈现视图控制器.

如果连续呈现多个视图控制器,从而构建一堆呈现的视图控制器,则在堆栈中较低的视图控制器上调用此方法会解除其直接子视图控制器以及堆栈上该子视图上方的所有视图控制器.发生这种情况时,只有最顶层的视图以动画方式被删除 ; 任何中间视图控制器都可以从堆栈中删除.最顶层的视图使用其模态过渡样式被忽略,这可能与堆栈中较低的其他视图控制器使用的样式不同.

问题是它不会发生什么.在我的场景中,thirdVC消失了,并显示secondVC被解雇的经典模态幻灯片到底部动画.

我究竟做错了什么 ?


编辑:

所以@codeFi的答案可能是在一个经典项目中,但问题在于我正在研究一个框架.因此,mainVC将在一个客户端应用程序,以及secondVCthirdVC在我的框架,在一个单独的故事板.mainVC除了在我的代码中引用它之外,我没有任何其他方式访问,所以很遗憾,unwind segues不是一个选项.

and*_*ehr 3

我一直遇到这个完全相同的问题,并且我已经通过将屏幕快照添加为子视图来设法解决该问题secondVC.view,如下所示:

if (self.presentedViewController.presentedViewController) {
    [self.presentedViewController.view addSubview:[[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO]];
}

[self dismissViewControllerAnimated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

不漂亮,但似乎有效。

注意:如果您secondVC有导航栏,则需要在拍摄屏幕快照并将快照作为子视图添加到 之间隐藏导航栏secondVC,否则快照将显示在导航栏下方,从而在拍摄期间看似显示双导航栏解雇动画。代码:

if (self.presentedViewController.presentedViewController) {
    UIView *snapshot = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
    [self.presentedViewController.navigationController setNavigationBarHidden:YES animated:NO];
    [self.presentedViewController.view addSubview:snapshot];
}

[self dismissViewControllerAnimated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)