自定义转场动画,在iOS7及以上的版本才开始出现的,在一些应用中,我们常常需要定制自定义的的跳转动画
1.遵守协议:<UIViewControllerAnimatedTransitioning>
2.协议的方法主要的是两个:
// 指定动画的持续时长 1. (NSTimeInterval)transitionDuration;
// 转场动画的具体内容 2. (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> typedef NS_ENUM(NSUInteger, HYBControllerTransitionType) {
kControllerTransitionPush = << ,
kControllerTransitionPop = <<
}; @interface HYBControllerTransition : NSObject <UIViewControllerAnimatedTransitioning> + (instancetype)transitionWithType:(HYBControllerTransitionType)transitionType
duration:(NSTimeInterval)duration; @end
#import "HYBControllerTransition.h"
#import "ViewController.h"
#import "DetailController.h" @interface HYBControllerTransition () @property (nonatomic, assign) HYBControllerTransitionType transitionType;
@property (nonatomic, assign) NSTimeInterval duration; @end @implementation HYBControllerTransition - (instancetype)init {
if (self = [super init]) {
self.transitionType = kControllerTransitionPush;
} return self;
} + (instancetype)transitionWithType:(HYBControllerTransitionType)transitionType
duration:(NSTimeInterval)duration {
HYBControllerTransition *transition = [[HYBControllerTransition alloc] init];
transition.transitionType = transitionType;
transition.duration = duration; return transition;
} #pragma mark - UIViewControllerAnimatedTransitioning
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
switch (self.transitionType) {
case kControllerTransitionPush: {
[self push:transitionContext];
break;
}
case kControllerTransitionPop: {
[self pop:transitionContext];
break;
}
default: {
break;
}
}
} - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return self.duration;
} - (void)animationEnded:(BOOL)transitionCompleted {
NSLog(@"%s", __FUNCTION__);
} #pragma mark - Private
- (void)pop:(id<UIViewControllerContextTransitioning>)transitionContext {
DetailController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
ViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView]; UIView *toImageView = toVC.isImg1 ? toVC.img1 : toVC.img2; UIView *tempView = containerView.subviews.lastObject; // 第一个view是fromVC.view
// 第二个view是push进来时所生成的toImageView截图
for (UIView *view in containerView.subviews) {
NSLog(@"%@", view);
if (fromVC.view == view) {
NSLog(@"YES");
}
} toImageView.hidden = YES;
tempView.hidden = NO;
// 必须保证将toVC.view放在最上面,也就是第一个位置
[containerView insertSubview:toVC.view atIndex:]; [UIView animateWithDuration:self.duration
delay:0.0
usingSpringWithDamping:0.55
initialSpringVelocity:/ 0.55
options:
animations:^{
fromVC.view.alpha = 0.0;
tempView.frame = [toImageView convertRect:toImageView.bounds toView:containerView];
} completion:^(BOOL finished) {
tempView.hidden = NO;
toImageView.hidden = NO;
[tempView removeFromSuperview]; [transitionContext completeTransition:YES]; for (UIView *view in containerView.subviews) {
NSLog(@"%@", view);
if (toVC.view == view) {
NSLog(@"YES");
}
}
}];
} - (void)push:(id<UIViewControllerContextTransitioning>)transitionContext {
ViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
DetailController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView]; UIView *fromImageView = fromVC.isImg1 ? fromVC.img1 : fromVC.img2;
UIView *tempView = [fromImageView snapshotViewAfterScreenUpdates:NO];
tempView.frame = [fromImageView convertRect:fromImageView.bounds toView:containerView]; UIView *toImageView = toVC.imgView; fromImageView.hidden = YES;
toVC.view.alpha = 0.0;
toImageView.hidden = YES; [containerView addSubview:toVC.view];
[containerView addSubview:tempView]; [UIView animateWithDuration:self.duration
delay:0.0
usingSpringWithDamping:0.55
initialSpringVelocity:/ 0.55
options:
animations:^{
toVC.view.alpha = 1.0;
tempView.frame = [toImageView convertRect:toImageView.bounds toView:containerView];
} completion:^(BOOL finished) {
tempView.hidden = YES;
toImageView.hidden = NO; [transitionContext completeTransition:YES];
}];
}
@end
使用遵守Nav协议的方法:
#pragma mark - UINavigationControllerDelegate
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController {
return nil;
} - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
if (operation == UINavigationControllerOperationPush) {
return [HYBControllerTransition transitionWithType:kControllerTransitionPush duration:0.75];
} else {
return [HYBControllerTransition transitionWithType:kControllerTransitionPop duration:0.75];
}
}