1 #import "ModelAnimationDelegate.h" 2 #import <UIKit/UIKit.h> 3 #import "MapVC.h" 4 #import "MapLiuLanViewController.h" 5 #import "MapCollectionViewCell.h" 6 7 @interface ModelAnimationDelegate ()<UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning> 8 9 @property (nonatomic, assign) BOOL isPresentAnimationing; 10 11 @end 12 13 @implementation ModelAnimationDelegate 14 15 // 视图弹出 16 - (void)presentViewAnimation:(id <UIViewControllerContextTransitioning>)transitionContext { 17 // 获取容器view 18 UIView *containerView = [transitionContext containerView]; 19 // 获取目标view 20 UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey]; 21 destinationView.alpha = 0; 22 // 将目标view添加到容器view 23 [containerView addSubview:destinationView]; 24 25 // 获取目标vc 26 MapLiuLanViewController *destinationVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 27 NSIndexPath *indexPath = destinationVC.indexPath; 28 29 // 获取来源vc 30 UINavigationController *naVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 31 MapVC *sourceVC = (MapVC *)naVC.topViewController; 32 // 获取来源view 33 UICollectionView *collectionView = sourceVC.collectionView; 34 MapCollectionViewCell *selectedCell = (MapCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath]; 35 36 // 获取动画开始位置大小 37 CGRect startFrame = [collectionView convertRect:selectedCell.frame toView:[UIApplication sharedApplication].keyWindow]; 38 39 UIImageView *animationImgView = [[UIImageView alloc] initWithFrame:startFrame]; 40 animationImgView.image = selectedCell.imgView.image; 41 animationImgView.contentMode = UIViewContentModeScaleAspectFill; 42 animationImgView.clipsToBounds = YES; 43 [containerView addSubview:animationImgView]; 44 45 // 获取动画结束位置大小 46 CGFloat w = WIDTH; 47 CGFloat h = w / animationImgView.image.size.width * animationImgView.image.size.height; 48 CGFloat x = 0; 49 CGFloat y = (HEIGHT - h) / 2.0; 50 CGRect endFrame = CGRectMake(x, y, w, h); 51 52 // 执行过渡动画 53 [UIView animateWithDuration:1.0 animations:^{ 54 animationImgView.frame = endFrame; 55 } completion:^(BOOL finished) { 56 [transitionContext completeTransition:YES]; 57 [UIView animateWithDuration:0.5 animations:^{ 58 destinationView.alpha = 1.0; 59 } completion:^(BOOL finished) { 60 [animationImgView removeFromSuperview]; 61 }]; 62 }]; 63 } 64 65 // 视图消失 66 - (void)dismissViewAnimation:(id <UIViewControllerContextTransitioning>)transitionContext { 67 // 获取容器view 68 UIView *containerView = [transitionContext containerView]; 69 // 获取目标view 70 UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey]; 71 destinationView.alpha = 0; 72 // 将目标view添加到容器view 73 [containerView addSubview:destinationView]; 74 75 // 获取目标vc 76 MapLiuLanViewController *destinationVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 77 NSIndexPath *indexPath = destinationVC.indexPath; 78 79 // 获取来源vc 80 UINavigationController *naVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 81 MapVC *sourceVC = (MapVC *)naVC.topViewController; 82 // 获取来源view 83 UICollectionView *collectionView = sourceVC.collectionView; 84 MapCollectionViewCell *selectedCell = (MapCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath]; 85 86 // 获取动画开始位置大小 87 CGRect startFrame = [collectionView convertRect:selectedCell.frame toView:[UIApplication sharedApplication].keyWindow]; 88 89 UIImageView *animationImgView = [[UIImageView alloc] initWithFrame:startFrame]; 90 animationImgView.image = selectedCell.imgView.image; 91 animationImgView.contentMode = UIViewContentModeScaleAspectFill; 92 animationImgView.clipsToBounds = YES; 93 [containerView addSubview:animationImgView]; 94 95 // 获取动画结束位置大小 96 CGFloat w = WIDTH; 97 CGFloat h = w / animationImgView.image.size.width * animationImgView.image.size.height; 98 CGFloat x = 0; 99 CGFloat y = (HEIGHT - h) / 2.0; 100 CGRect endFrame = CGRectMake(x, y, w, h); 101 102 // 执行过渡动画 103 [UIView animateWithDuration:1.0 animations:^{ 104 animationImgView.frame = endFrame; 105 } completion:^(BOOL finished) { 106 [transitionContext completeTransition:YES]; 107 [UIView animateWithDuration:0.5 animations:^{ 108 destinationView.alpha = 1.0; 109 } completion:^(BOOL finished) { 110 [animationImgView removeFromSuperview]; 111 }]; 112 }]; 113 } 114 115 #pragma mark ----- UIViewControllerTransitioningDelegate协议方法 ----- 116 117 - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { 118 _isPresentAnimationing = YES; 119 return self; 120 } 121 122 - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { 123 _isPresentAnimationing = NO; 124 return self; 125 } 126 127 128 #pragma mark ----- UIViewControllerAnimatedTransitioning协议方法 ----- 129 130 - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext { 131 return 1.0; 132 } 133 134 - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { 135 _isPresentAnimationing ? [self presentViewAnimation:transitionContext] : [self dismissViewAnimation:transitionContext]; 136 } 137 138 @end