自定义 segue 和导航控制器动画故障

Posted

技术标签:

【中文标题】自定义 segue 和导航控制器动画故障【英文标题】:Custom segue and navigation controller animation glitch 【发布时间】:2014-07-19 04:36:23 【问题描述】:

我使用自定义 segue,看起来像使用导航控制器放大。当 segue 完成并调用方法 pushViewController: animated: 时,会出现故障效果。导航栏立即出现,并将滚动视图的内容与其高度(88 像素)的值一起放在下面。下面的动画清楚地代表了效果:http://s7.postimg.org/7in5s980r/image.gif 可以看到,在 segue 的最后阶段,scrollView 的内容移动得非常快。

这是segue的代码:

- (void)perform 
    UIViewController *sourceViewController = self.sourceViewController;
    UIViewController *destinationViewController = self.destinationViewController;

    // Add the destination view as a subview, temporarily
    [sourceViewController.view addSubview:destinationViewController.view];

    // Transformation start scale
    destinationViewController.view.transform = CGAffineTransformMakeScale(0.05, 0.05);

    // Store original centre point of the destination view
    CGPoint originalCenter = destinationViewController.view.center;
    // Set center to start point of the button
    destinationViewController.view.center = self.originatingPoint;

    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^


                         destinationViewController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
                         destinationViewController.view.center = originalCenter;
                     
                     completion:^(BOOL finished)

                         [destinationViewController.view removeFromSuperview];
                         [sourceViewController.navigationController pushViewController:destinationViewController animated:NO];

                     ];

我认为,问题在于通常(如果是推送转场)ViewController 会稍微降低内容(对于导航栏的高度)并在转场期间执行此操作。但现在,它将 segue 视为自定义并忽略导航栏(但显示它)并显示部分内容被导航栏重叠。当 Navigation Controller 呈现新的 VC 时,它会计算 NavBar 的高度并立即放下内容。我认为,可能有办法在 segue 期间设置 scrollView 的属性,例如内容大小和起始点,但不知道如何实现。

【问题讨论】:

【参考方案1】:

我现在没有 XCode,所以这是我的猜测。

所以,首先你做了

// Add the destination view as a subview, temporarily
[sourceViewController.view addSubview:destinationViewController.view];

然后,你打电话

animateWithDuration:delay:options:animations:completion:

你看到的动画是什么。如果我是对的,这会导致整个视图覆盖导航视图,因为您将此视图添加到顶部。

完成后,此视图将从超级视图中删除,但随后您将其推送到导航视图控制器中。这一步会导致您在动画中看到的跳跃。

这就是跳转发生的原因:覆盖整个视图的视图被移除(突然消失)。这让导航视图再次出现(导航栏显示),然后视图被推入导航视图控制器,它现在嵌入到导航视图中。这就是为什么它看起来像动画故障并且移动得非常快的原因。

【讨论】:

几乎是正确的,实际上,原因很清楚:故障是由于在动画中显示 VC 而没有为 NavBar 填充并稍后添加此填充。但我问了如何解决这个问题的任何想法。 我能想到的一件事是,您可以将一个新的空视图推送到导航视图堆栈中。然后,该新视图可以添加destinationView 作为其子视图并对动画进行动画处理。 我已经在 ios 7 及更高版本中解决了这个问题,只需在故事板中添加透明 (alpha=0) NavBar。将添加有问题的解决方案。 iOS 6 的问题仍然悬而未决,因为添加透明的 NavBar 没有帮助。 @RichardTopchiy 您能否扩展您的解决方案?如果可以基本上创建一个自定义替代方案来替代推送过渡,其中导航栏从一个 VC 平滑过渡到另一个,而无需调整新视图的大小。 @Nuthinking,视图控制器转换是要走的路。我现在不会使用我提供的有问题的代码。这是关于自定义转换的链接:objc.io/issues/5-ios7/view-controller-transitions

以上是关于自定义 segue 和导航控制器动画故障的主要内容,如果未能解决你的问题,请参考以下文章

自定义推送 segue 动画

使用情节提要逆转自定义 Segue

在没有 UINavigationController 的情况下推送 Segue 动画

自定义 segue 到导航控制器层次结构中的特定子视图

如何通过 viewControllers 的导航控制器设置自定义 segue 操作

Swift:嵌入在导航控制器中的视图之间的自定义segue