iOS动画技术——自定义视图过渡动画

树形结构导航自定义过渡动画

通过实现UIViewControllerAnimatedTransitioning协议中的两个方法来自定义视图的过渡动画。

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

NS_ASSUME_NONNULL_BEGIN

@interface SliderTransitionAnimator : NSObject

<UIViewControllerAnimatedTransitioning>

@property (nonatomic, assign) BOOL isPresenting;

@end

NS_ASSUME_NONNULL_END
#import "SliderTransitionAnimator.h"

@implementation SliderTransitionAnimator

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewKey];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewKey];
    
    if (self.isPresenting)
    {
        [transitionContext.containerView addSubview:fromVC.view];
        [transitionContext.containerView addSubview:toVC.view];
        
        toVC.view.frame = transformedStartFrame;
        [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
        {
            toVC.view.frame = transformedEndFrame;
        } completion:^(BOOL finished)
        {
            [transitionContext completeTransition:YES];
        }];
    }
    else
    {
        [transitionContext.containerView addSubview:toVC.view];
        [transitionContext.containerView addSubview:fromVC.view];
        
        [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
        {
            fromVC.view.frame = tranformedStartFrame;
        } completion:^(BOOL finished)
        {
            [transitionContext completeTransition:YES];
        }];
    }
}

具体使用是在视图控制器中实现UINavigationControllerDelegate协议中的方法:

#import "ViewController.h"
#import "SliderTransitionAnimator.h"

@interface ViewController () <UINavigationControllerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
}

-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                 animationControllerForOperation:(UINavigationControllerOperation)operation
                                              fromViewController:(UIViewController *)fromVC
                                                toViewController:(UIViewController *)toVC
{
    SliderTransitionAnimator *animator = [[SliderTransitionAnimator alloc] init];
    animator.isPresenting = (operation == UINavigationControllerOperationPop) ? NO : YES;
    return animator;
}

@end

模态导航自定义过渡动画

视图控制器需要实现UIViewControllerTransitioningDelegate协议中的两个方法:

#import "ViewController.h"
#import "SliderTransitionAnimator.h"

@interface ViewController () <UIViewControllerTransitioningDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
}

-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                 presentingController:(UIViewController *)presenting
                                                                     sourceController:(UIViewController *)source
{
    SliderTransitionAnimator *transitioning = [[SliderTransitionAnimator alloc] init];
    transitioning.isPresenting = YES;
    return transitioning;
}

-(id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    SliderTransitionAnimator *transitioning = [[SliderTransitionAnimator alloc] init];
    transitioning.isPresenting = NO;
    return transitioning;
}

@end

实例:使用HUAnimator自定义过渡动画框架

#import <UIKit/UIKit.h>
#import "HUTransitionAnimator.h"

typedef NS_ENUM(NSUInteger, HUTransitionType)
{
    Transition6Style,
    TransitionGhost,
    TransitionVerticalLines,
    TransitionHorizontalLines,
};

@interface ViewController : UIViewController

<UINavigationControllerDelegate,
UIViewControllerTransitioningDelegate>

@property (nonatomic, assign) HUTransitionType transitionType;

@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
        
    self.navigationController.delegate = self;
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue
                sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"TransitionGhost"])
    {
        self.transitionType = TransitionGhost;
    }
    else if ([[segue identifier] isEqualToString:@"TransitionVerticalLines"])
    {
        _transitionType = TransitionVerticalLines;
    }
    else if ([[segue identifier] isEqualToString:@"TransitionHorizontalLines"])
    {
        _transitionType = TransitionHorizontalLines;
    }
    else if ([[segue identifier] isEqualToString:@"Transition6Style"])
    {
        _transitionType = Transition6Style;
    }
    else
    {
        UIViewController *destinationViewController = [segue destinationViewController];
        destinationViewController.transitioningDelegate = self;
    }
}

#pragma mark - UINavigationControllerDelegate
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                 animationControllerForOperation:(UINavigationControllerOperation)operation
                                              fromViewController:(UIViewController *)fromVC
                                                toViewController:(UIViewController *)toVC
{
    HUTransitionAnimator *animator;
    
    switch (_transitionType)
    {
        case TransitionGhost:
            animator = [[HUTransitionGhostAnimator alloc] init];
            break;
        case TransitionVerticalLines:
            animator = [[HUTransitionVerticalLinesAnimator alloc] init];
            break;
        case TransitionHorizontalLines:
            animator = [[HUTransitionHorizontalLinesAnimator alloc] init];
            break;
        default:
            animator = [[HUTransitionAnimator alloc] init];
            break;
    }
    animator.presenting = (operation == UINavigationControllerOperationPop) ? NO : YES;
    return animator;
}

#pragma mark - UIViewControllerTransitioningDelegate
-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                 presentingController:(UIViewController *)presenting
                                                                     sourceController:(UIViewController *)source
{
    id transitioning = [[HUTransitionVerticalLinesAnimator alloc] init];
    return transitioning;
}

-(id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    id transitioning = [[HUTransitionHorizontalLinesAnimator alloc] init];
    return transitioning;
}

@end

猜你喜欢

转载自blog.csdn.net/run_in_road/article/details/113406951