10

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

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

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

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

所以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

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

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

但是当我想解散时thirdVC,我想要的是直接回到mainVC。所以我从以下调用thirdVC

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

这样,我dismissViewControllerAnimated:直接调用mainVC(由 引用self.presentingViewController.presentingViewController),我期望thirdVC用动画解除,而secondVC没有动画就消失。

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

呈现视图控制器负责关闭它呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,它会自动将消息转发到呈现的视图控制器。

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

问题是这不是发生的事情。在我的场景中,thirdVC消失了,并secondVC使用经典的模态幻灯片到底部动画显示被解雇。

我究竟做错了什么 ?


编辑 :

所以@codeFi 的答案可能是在一个经典项目中工作,但这里的问题是我正在开发一个框架。mainVC在客户端应用程序中也是如此,secondVC并且thirdVC在我的框架中,在一个单独的故事板中。除了在我的代码中引用它之外,我无法以mainVC任何其他方式访问它,因此不幸的是,展开 segues 不是这里的选项。

4

2 回答 2

3

我一直有这个完全相同的问题,我设法通过将屏幕快照添加为子视图来直观地解决它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];
于 2014-11-10T23:16:10.357 回答
2

我有同样的问题,我已经通过使用 UnwindSegues 修复了它。

基本上,您所要做的就是在您想要继续的 ViewController 中添加一个 IBAction Unwind Segue 方法,然后在 IB 中将 Exit 操作连接到您的 Unwind Segue 方法。

例子:

假设您有三个 ViewController(VC1、VC2、VC3)并且您想从 VC3 转到 VC1。

步骤 1 向 VC1 添加一个方法,如下所示:

- (IBAction)unwindToVC1:(UIStoryboardSegue*)sender
{
}

第 2 步 进入 Interface Builder 到 VC3 并选择它。然后按住 CTRL 键从您的 VC 图标拖动到 Exit 图标并选择您刚刚在 VC1 中添加的方法。

添加 Unwind Segue

第 3 步 当仍在 IB 中并选择 VC3 时,选择您的 Unwind Segue 并在 Attributes Inspector 中添加一个 Segue Identifier。

在此处输入图像描述 在此处输入图像描述

步骤 4 转到需要执行 segue(或关闭 VC)的 VC3 并添加以下内容:

[self performSegueWithIdentifier:@"VC1Segue" sender:self];
于 2014-09-24T13:40:25.833 回答