2014-09-24 62 views
8

我正在构建一种中间有分支的复杂应用程序。解除堆栈中较低的ViewController的行为并不像预期的那样

在应用程序的某个位置,显示了一个特定的UIViewController,我们将其称为mainViewController(缩写为mainVC)。

mainVC提出了另一个视图控制器,通过代码,使用下面的代码(I去掉隐私的原因它的一部分):

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

所以​​稍后将呈现另一视图控制器,称为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 

正如你可以看到这个赛格瑞呈现目的地视图控制器模态(通过使用presentViewController:)用自定义动画(从右到左滑动)。

所以基本上到这里一切都很好。我用典型的模态动画(从底部向上滑动)呈现​​,并用我的自定义过渡呈现thirdVC

但是,当我想解雇thirdVC时,我想要直接返回到mainVC。所以我所说的从thirdVC如下:

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

这样的话,我直接调用dismissViewControllerAnimated:mainVC(由self.presentingViewController.presentingViewController引用),和我期待的thirdVC与动画中被解雇,而​​没有动画就消失。

随着苹果说,在UIViewController类文档:

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

如果连续介绍几个视图控制器,从而构建一个 堆栈呈现视图控制器,调用视图 控制器这种方法在堆栈中较低驳回其直接子视图 控制器及以上的所有视图控制器那个孩子在堆栈。 当发生这种情况时,只有最顶级的观点被取消动画 时尚;任何中间视图控制器都会从 堆栈中简单地删除。最顶端的视图使用其模式转换 样式被忽略,这可能与堆栈中较低的其他视图控制器 使用的样式不同。

问题是,它不会发生什么。在我的场景中,thirdVC消失,并且显示​​被经典模态幻灯片解散为底部动画。

我在做什么错?


编辑:

所以@ codeFi的回答以经典的项目可能是工作,但这里的问题是,我工作的一个框架。因此,mainVC将位于客户端应用程序中,并且​​和thirdVC位于我的框架中,位于单独的故事板中。我不能以任何其他方式访问mainVC而不是在我的代码中引用它,所以不幸的是,这里展开的segues不是一个选项。

+1

这种行为的改变发生在iOS 8中,7它确实工作正常。我正在尝试解决它。 – theLastNightTrain 2014-10-21 16:23:13

+0

@theLastNightTrain:嗯,你是对的,它只发生在iOS 8上。让我知道你是否发现任何东西.. – rdurand 2014-10-22 07:17:57

+0

@theLastNightTrain:有没有更新?我很乐意提供一个解决这个问题的答案赏金.. – rdurand 2014-10-27 13:58:19

回答

2

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

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

[self dismissViewControllerAnimated:YES completion:nil]; 

不漂亮,但它似乎工作。

注:如果你的​​有一个导航栏,你将需要隐藏的导航栏快照屏幕并添加快照作为一个子视图之间​​,否则快照就会出现在导航栏下方,从而看起来在解雇动画期间显示双导航栏。代码:

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]; 
+0

谢谢,我会测试,让你知道它是如何工作的。 – rdurand 2014-11-12 09:19:25

+1

似乎很好地工作..它会很好,直到他们修复它。谢谢 ! – rdurand 2014-11-12 10:46:45

+0

请注意,如果您的'secondVC'有一个导航栏,则需要在快照屏幕和将快照添加到'secondVC'的子视图之间隐藏导航栏,否则快照将显示在导航栏下方,从而看起来在解雇动画期间显示双导航栏。 – rhelba 2014-11-12 14:36:35

1

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

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

例子:

比方说,你有三个ViewControllers(VC1,VC2,VC3),你想去从VC3 VC1到。

步骤1 添加方法VC1类似如下:

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

步骤2 转到在界面生成器VC3和选择它。然后按住CTRL拖动你的VC图标到Exit图标,并选择你在VC1中添加的方法。

Add Unwind Segue

步骤3 同时还在IB,并与选定的VC3,选择您放松身心Segue公司,并在属性检查器中添加一个Segue公司标识。

enter image description here enter image description here

步骤4 转到VC3,你需要执行你的赛格瑞(或者解聘VC),并添加以下内容:

[self performSegueWithIdentifier:@"VC1Segue" sender:self]; 
+0

嘿!感谢您的回答。过去我已经使用过放松式赛段,但在这种情况下它们不是一种选择。我没有提到保持“简单”的问题是第二个和第三个视图控制器在一个框架内。所以基本上,主要的VC在客户端的应用程序中,另外两个在框架中分离(因此是另一个故事板)。对不起,这不是说我的问题:) – rdurand 2014-09-24 13:46:11

相关问题