树形结构导航自定义过渡动画
通过实现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