如何实现自定义segue动画?

Posted

技术标签:

【中文标题】如何实现自定义segue动画?【英文标题】:How to implement custom segue animations? 【发布时间】:2014-09-24 11:32:29 【问题描述】:

我将UIStoryboardSegue 子类化以执行自定义转场动画。为了使动画可见,我必须将来自目标 ViewController 的视图添加为临时视图。执行动画后,我将删除临时视图并通过 (presentViewController:animated:NO) 呈现最终的 ViewController

然而,这会导致以下警告:“开始/结束外观转换的不平衡调用”

如果我保留我的临时视图并且不删除它,则不会出现警告,但最终视图不再响应触摸事件。如何摆脱这个警告?

我的自定义转场代码:

-(void)perform 

    UIViewController *sourceViewController = self.sourceViewController;
    UIViewController *destinationViewController = self.destinationViewController;

    destinationViewController.view.alpha = 0.;
    destinationViewController.view.transform = CGAffineTransformScale(destinationViewController.view.transform, 4.0, 4.0);

    [sourceViewController.view addSubview:destinationViewController.view];

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

                         destinationViewController.view.transform = CGAffineTransformScale(destinationViewController.view.transform, 0.25, 0.25);
                         destinationViewController.view.alpha = 1.;
                     
                     completion:^(BOOL finished)
                         [destinationViewController.view removeFromSuperview]; // remove from temp super view
                         [sourceViewController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC
                     ];

【问题讨论】:

【参考方案1】:

我正在参加 4 UIStoryboardSegue 类型的课程。 2 用于动画开始和休息 2 用于动画停止。所以我将分享 4 个类的所有代码。请尝试解决这个问题。

CustomSegue.h

 #import <UIKit/UIKit.h>
 @interface CustomSegue : UIStoryboardSegue

 // Originating point for animation
 @property CGPoint originatingPoint;
 @property CGRect Startingframe;
 @end

CustomSegue.m

 #import "CustomSegue.h"
 @implementation CustomSegue

 - (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
   float width = 320;
   float height = 480;

   float x_Scale = self.Startingframe.size.width/width;
   float Y_Scale = self.Startingframe.size.height/height;

   destinationViewController.view.transform = CGAffineTransformMakeScale(x_Scale, Y_Scale);

   // 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:0.5
                      delay:0.0
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^
                
                     // Grow!
                      destinationViewController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);

                     destinationViewController.view.center = originalCenter;
                 
                 completion:^(BOOL finished)
                
                     [destinationViewController.view removeFromSuperview]; // remove from temp super view
                     [sourceViewController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC
                 ];
 

 @end

CustomUnwindSegue.h

 #import <UIKit/UIKit.h>
 @interface CustomUnwindSegue : UIStoryboardSegue

 // Target point to animate to (on the button)
 @property CGPoint targetPoint;
 @property CGRect endFrame;

 @end

CustomUnwindSegue.m

 #import "CustomUnwindSegue.h"

 @implementation CustomUnwindSegue

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

    // Transformation End scale
    float width = 320;
    float height = 480;

    float x_Scale = self.endFrame.size.width/width;
    float Y_Scale = self.endFrame.size.height/height;
    // Add view to super view temporarily
    [sourceViewController.view.superview insertSubview:destinationViewController.view atIndex:0];

    [UIView animateWithDuration:0.5
                      delay:0.0
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^
                     // Shrink!
                     sourceViewController.view.transform = CGAffineTransformMakeScale(x_Scale, Y_Scale);
                     sourceViewController.view.center = self.targetPoint;
                 
                 completion:^(BOOL finished)
                     [destinationViewController.view removeFromSuperview]; // remove from temp super view
                     [sourceViewController dismissViewControllerAnimated:NO completion:NULL]; // dismiss VC
                 ];


@end

只需将您的动作与此自定义转场动画连接起来,如下所示:

【讨论】:

不能将此作为答案,因为它只是一个不同的过渡动画。问题仍然相同。它会导致同样的警告!

以上是关于如何实现自定义segue动画?的主要内容,如果未能解决你的问题,请参考以下文章

从左到右使用动画进行 Segue

使用自定义 segue 动画将一个视图替换为另一个视图?

iOS - 创建自定义过渡动画

使用以编程方式创建的 segue IOS 调用自定义过渡动画师

swift 4 - segue 动画完成后如何在目标视图控制器中运行代码?

如何从自定义 UITableViewCell 触发 segue - iOS7