OC轉場動畫UIViewControllerTransitioningDelegate
阿新 • • 發佈:2018-11-12
該專案一共兩個介面,第一個的只有一個SystemAnimationViewController只有UICollecitonView,第二個介面ImgDetailViewController只有一個UIImageView,程式碼簡單,這裡不做陳述
下面是轉場動畫的所有程式碼:
// // ModelAnimationDelegate.m // Demo // // Created by Apple on 2018/11/8. // Copyright © 2018年 cqytjr. All rights reserved. // #import "ModelAnimationDelegate.h" #import "SystemAnimationViewController.h" #import "SystemAnimaitonCollectionViewCell.h" #import "ImgDetailViewController.h" /* 1.描述ViewController轉場的: UIViewControllerTransitioningDelegate自定義模態轉場動畫時使用 ,UINavigationControllerDelegate 自定義navigation轉場動畫時使用。, UITabBarControllerDelegate 自定義tab轉場動畫時使用。 2.定義動畫內容的 UIViewControllerAnimatedTransitioning,UIViewControllerInteractiveTransitioning 3.表示動畫上下文的 UIViewControllerContextTransitioning */ @interface ModelAnimationDelegate ()< UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate> @property (nonatomic, assign) BOOL isPresentAnimationing; @end @implementation ModelAnimationDelegate #pragma mark UIViewControllerAnimatedTransitioning // 檢視彈出 - (void)presentViewAnimation:(id <UIViewControllerContextTransitioning>)transitionContext { // 獲取容器view UIView *containerView = [transitionContext containerView]; // 獲取目標view UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey]; destinationView.alpha = 0; // 將目標view新增到容器view [containerView addSubview:destinationView]; // 獲取目標vc ImgDetailViewController *destinationVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; NSIndexPath *indexPath = destinationVC.indexPath; // 獲取來源vc UINavigationController *naVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; SystemAnimationViewController *sourceVC = (SystemAnimationViewController *)naVC.topViewController; // 獲取來源view UICollectionView *collectionView = sourceVC.collectionView; SystemAnimaitonCollectionViewCell *selectedCell = (SystemAnimaitonCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath]; // 獲取動畫開始位置大小 CGRect startFrame = [collectionView convertRect:selectedCell.frame toView:[UIApplication sharedApplication].keyWindow]; UIImageView *animationImgView = [[UIImageView alloc] initWithFrame:startFrame]; animationImgView.image = selectedCell.img.image; animationImgView.contentMode = UIViewContentModeScaleAspectFit; animationImgView.clipsToBounds = YES; [containerView addSubview:animationImgView]; // 獲取動畫結束位置大小 CGRect endFrame = destinationVC.img.frame; // 執行過渡動畫 [UIView animateWithDuration:1.0 animations:^{ animationImgView.frame = endFrame; NSLog(@"-----:%f %f %f %f",startFrame.origin.x,startFrame.origin.y,startFrame.size.width,startFrame.size.height); NSLog(@"-----:%f %f %f %f",endFrame.origin.x,endFrame.origin.y,endFrame.size.width,endFrame.size.height); } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; [UIView animateWithDuration:1.0 animations:^{ destinationView.alpha = 1.0; } completion:^(BOOL finished) { [animationImgView removeFromSuperview]; }]; }]; } // 檢視消失 - (void)dismissViewAnimation:(id <UIViewControllerContextTransitioning>)transitionContext { // 獲取容器view UIView *containerView = [transitionContext containerView]; // 獲取目標view UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey]; destinationView.alpha = 0; // 將目標view新增到容器view [containerView addSubview:destinationView]; UINavigationController *naVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // 獲取目標vc SystemAnimationViewController *destinationVC = naVC.topViewController; // NSIndexPath *indexPath = destinationVC.indexPath; // // 獲取來源vc ImgDetailViewController *sourceVC = (ImgDetailViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; NSIndexPath *indexPath = sourceVC.indexPath; // 獲取來源view UICollectionView *collectionView = destinationVC.collectionView; SystemAnimaitonCollectionViewCell *selectedCell = (SystemAnimaitonCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath]; // 獲取動畫開始位置大小 CGRect startFrame = sourceVC.img.frame; UIImageView *animationImgView = [[UIImageView alloc] initWithFrame:startFrame]; animationImgView.image = selectedCell.img.image; animationImgView.contentMode = UIViewContentModeScaleAspectFill; animationImgView.clipsToBounds = YES; [containerView addSubview:animationImgView]; animationImgView.contentMode = UIViewContentModeScaleAspectFit; animationImgView.clipsToBounds = YES; // 獲取動畫結束位置大小 CGRect endFrame = [collectionView convertRect:selectedCell.frame toView:[UIApplication sharedApplication].keyWindow]; // 執行過渡動畫 [UIView animateWithDuration:1.0 animations:^{ animationImgView.frame = endFrame; NSLog(@"-----:%f %f %f %f",startFrame.origin.x,startFrame.origin.y,startFrame.size.width,startFrame.size.height); NSLog(@"-----:%f %f %f %f",endFrame.origin.x,endFrame.origin.y,endFrame.size.width,endFrame.size.height); sourceVC.view.hidden = YES; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; [UIView animateWithDuration:1.0 animations:^{ destinationView.alpha = 1.0; } completion:^(BOOL finished) { [animationImgView removeFromSuperview]; }]; } - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext { return 10.0; } - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { _isPresentAnimationing ? [self presentViewAnimation:transitionContext] : [self dismissViewAnimation:transitionContext]; } #pragma mark UIViewControllerTransitioningDelegate - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { _isPresentAnimationing = YES; return self; } - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { _isPresentAnimationing = NO; return self; } @end