iOS - 创建自定义推送转场动画

3

我正在尝试创建一个推送动画,其中源VC垂直向下滑出屏幕,目标VC从垂直向上进入屏幕。我的自定义segue似乎几乎实现了这种动画,然而,在目标VC出现时动画不起作用。这是我的-perform segue。

-(void)perform
{
    UIViewController *sourceVC =  self.sourceViewController;
    UIViewController *destVC = self.destinationViewController;
    [sourceVC.view addSubview:destVC.view];

    float width = sourceVC.view.frame.size.width;
    float height = sourceVC.view.frame.size.height;

    destVC.view.frame = CGRectMake(0, 560, width, height);

    [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveLinear
                     animations:^{
                         [destVC.view removeFromSuperview];
                         sourceVC.view.frame = CGRectMake(0, 560, width, height);
                     } completion:^(BOOL finished) {
                         [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
                             destVC.view.frame = CGRectMake(0, 0, destVC.view.frame.size.width, destVC.view.frame.size.height);
                         } completion:^(BOOL finished) {
                             [sourceVC.navigationController pushViewController:destVC animated:NO];
                         }];
                     }];
}

第二个动画没有起作用。你有何想法?感谢任何帮助。
1个回答

3

我需要创建一个符合UIViewControllerAnimatedTransitioning标准的自定义Animator类。

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SAAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end

接着,我实现了所需的方法。

@implementation SAAnimator

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.2;
}
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        fromViewController.view.userInteractionEnabled = NO;

        [[transitionContext containerView]addSubview:fromViewController.view];
        [[transitionContext containerView]addSubview:toViewController.view];

    toViewController.view.frame = CGRectMake(0, 560, toViewController.view.frame.size.width, toViewController.view.frame.size.height);

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
            fromViewController.view.frame = CGRectMake(0, 560, fromViewController.view.frame.size.width, fromViewController.view.frame.size.height);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
                toViewController.view.frame = CGRectMake(0, 0, toViewController.view.frame.size.width, toViewController.view.frame.size.height);
            } completion:^(BOOL finished) {
                [transitionContext completeTransition:YES];
            }];
        }];
}
@end

在我的视图控制器中执行推送Segue时,我认为非常简单,只需使该类符合UINavigationControllerDelegate并实现此方法即可。

#pragma mark - Animated Transiton

-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    if (operation == UINavigationControllerOperationPush) {
        SAAnimator * animator = [SAAnimator new];
        return  animator;
    }
    return nil;
}

在prepareForSegue方法中设置导航控制器的代理

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"toCreateVC"]) {
        self.navigationController.delegate = self;
    }
}

这是一个很好的解决方案。谢谢!我还想补充一点,你可以在viewWillDisappear方法中将导航控制器的代理重置为nil,以便将推送转场动画重置为默认值。 - Ethan G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接