ios – 在堆栈中较低的位置解除ViewController的行为不符合预期

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

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

mainVC通过代码使用以下代码呈现另一个视图控制器(出于隐私原因,我删除了部分代码):

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SecondaryStoryboard" bundle:secondaryBundle];
SecondViewController *secondVC = [storyboard instantiateInitialViewController];
[self presentViewController:secondVC animated:YES completion:nil];

因此,第二个VC将在稍后呈现另一个名为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

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

所以基本上到这里一切都很好.我用经典的模态动画(从底部向上滑动)呈现第二个VC,并使用我的自定义过渡呈现第三个VC.

但是当我想要解雇第三个VC时,我想要的是直接回到mainVC.所以我从第三个VC调用以下内容:

self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:_animate completion:nil];

这样,我正在调用dismissViewControllerAnimated:直接在mainVC上调用(由self.presentingViewController.presentingViewController引用),我期待第三个VC被动画解散,而第二个VC只是在没有动画的情况下消失.

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

The presenting view controller is responsible for dismissing the view
controller it presented
. If you call this method on the presented view
controller itself,it automatically forwards the message to the
presenting view controller.

If you present several view controllers in succession,thus building a
stack of presented view controllers,calling this method on a view
controller lower in the stack dismisses its immediate child view
controller and all view controllers above that child on the stack
.
When this happens,only the top-most view is dismissed in an animated
fashion
; any intermediate view controllers are simply removed from the
stack. The top-most view is dismissed using its modal transition
style,which may differ from the styles used by other view controllers
lower in the stack.

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

我究竟做错了什么 ?

编辑:

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

解决方法

我一直有这个完全相同的问题,我已经设法通过将屏幕快照添加到secondVC.view的子视图来进行视觉处理,如下所示:
if (self.presentedViewController.presentedViewController) {
    [self.presentedViewController.view addSubview:[[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO]];
}

[self dismissViewControllerAnimated:YES completion:nil];

不漂亮,但它似乎工作.

注意:如果您的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];

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...