利用轉場動畫實現(這裡不說轉場動畫),主要就是幾個坐標的轉換:將cell上的imageView快照生成一個snapView(直接創建一個ImageVIew也一樣), 在將cell上image的frame 坐標轉換到containerView上,在將snapView放大到目標尺寸 (首先你要知道轉場動...
利用轉場動畫實現(這裡不說轉場動畫),主要就是幾個坐標的轉換:將cell上的imageView快照生成一個snapView(直接創建一個ImageVIew也一樣), 在將cell上image的frame 坐標轉換到containerView上,在將snapView放大到目標尺寸 (首先你要知道轉場動畫時怎麼一回事)。
下麵是主要代碼,一個自定義類繼承自NSObject。實現了UINavigationControllerDelegate、UIViewControllerAnimatedTransitioning協議
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { // 獲取當前的控制器 UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; // 獲取將要轉向的控制器 UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // 獲取容器視圖 UIView *containerView = [transitionContext containerView]; UICollectionView *collectionView ; UIImageView *contentImageView; if (self.opration == PushAnimationOprationPush) { ViewController *from = (ViewController *)fromVC; collectionView = from.collectionView; contentImageView = [toVC valueForKey:@"_contentImageView"]; }else { ViewController *to = (ViewController *)toVC; collectionView = to.collectionView; contentImageView = [fromVC valueForKey:@"_contentImageView"]; } // 獲取選中的cell 的indexpath NSArray *selectedItems = [collectionView indexPathsForSelectedItems]; // 根據indexpath 獲取 cell CusCollectionViewCell *cell = (CusCollectionViewCell *)[collectionView cellForItemAtIndexPath:[selectedItems firstObject]]; UIView *snapView; CGRect snapViewFrame; CGRect snapViewTargetFrame; if (self.opration == PushAnimationOprationPush) { // 截取cell 上contentImage 的快照 snapView = [cell.contentImage snapshotViewAfterScreenUpdates:NO]; // 根據contentImage在cell上的坐標 轉換到 containerView上 snapViewFrame = [containerView convertRect:cell.contentImage.frame fromView:cell.contentImage.superview]; // 獲取目標控制器上要顯示的 imageView,並根據該imageView的尺寸位置,轉換到 容器視圖上,成為snapView 最終尺寸。 snapViewTargetFrame = [containerView convertRect:contentImageView.frame fromView:contentImageView.superview]; }else { snapView = [contentImageView snapshotViewAfterScreenUpdates:NO]; snapViewFrame = [containerView convertRect:contentImageView.frame fromView:contentImageView.superview]; snapViewTargetFrame = [containerView convertRect:cell.contentImage.frame fromView:cell.contentImage]; } snapView.frame = snapViewFrame; toVC.view.alpha = 0; [containerView addSubview:toVC.view]; [containerView addSubview:snapView]; contentImageView.hidden = YES; cell.contentImage.hidden = YES; [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:0.6f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{ snapView.frame = snapViewTargetFrame; toVC.view.alpha = 1.0; } completion:^(BOOL finished) { contentImageView.hidden = NO; cell.contentImage.hidden = NO; [snapView removeFromSuperview]; [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; }
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { if (operation == UINavigationControllerOperationPush) { self.opration = PushAnimationOprationPush; }else if (operation == UINavigationControllerOperationPop) { self.opration = PushAnimationOprationPop; } return self; } - (void)start { self.nav.delegate = self; } /** 為目標控制器添加一個tap手勢,返回上一個控制器 */ - (void)tapGestureToPopWithController:(UIViewController *)targetVC { self.targetViewController = targetVC; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGesture:)]; [targetVC.view addGestureRecognizer:tapGesture]; } - (void)tapGesture:(UITapGestureRecognizer *)gesture { [self.targetViewController.navigationController popViewControllerAnimated:YES]; }