| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 | 
							- //
 
- //  HXPhotoInteractiveTransition.m
 
- //  HXPhotoPickerExample
 
- //
 
- //  Created by Silence on 2017/10/28.
 
- //  Copyright © 2017年 Silence. All rights reserved.
 
- //
 
- #import "HXPhotoInteractiveTransition.h"
 
- #import "HXPhotoPreviewViewController.h"
 
- #import "HXPhotoViewController.h"
 
- #import "HXPhotoPreviewBottomView.h"
 
- @interface HXPhotoInteractiveTransition ()<UIGestureRecognizerDelegate>
 
- @property (nonatomic, weak) id<UIViewControllerContextTransitioning> transitionContext;
 
- @property (nonatomic, weak) HXPhotoPreviewViewController *vc;
 
- @property (nonatomic, weak) HXPhotoViewController *toVC;
 
- @property (strong, nonatomic) UIView *bgView;
 
- @property (weak, nonatomic) HXPhotoViewCell *tempCell;
 
- @property (weak, nonatomic) HXPhotoPreviewViewCell *fromCell;
 
- @property (assign, nonatomic) CGRect imageInitialFrame;
 
- @property (assign, nonatomic) CGPoint transitionImgViewCenter;
 
- @property (assign, nonatomic) CGFloat beginX;
 
- @property (assign, nonatomic) CGFloat beginY;
 
- @property (assign, nonatomic) CGPoint slidingGap;
 
- @property (strong, nonatomic) UIPanGestureRecognizer *panGesture;
 
- @property (assign, nonatomic) BOOL startPop;
 
- @property (assign, nonatomic) BOOL isFinished;
 
- @property (assign, nonatomic) BOOL beginInterPercentCompletion;
 
- @end
 
- @implementation HXPhotoInteractiveTransition
 
- - (void)addPanGestureForViewController:(UIViewController *)viewController {
 
-     self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognizeDidUpdate:)];
 
-     self.slidingGap = CGPointZero;
 
-     self.panGesture.delegate = self;
 
-     self.vc = (HXPhotoPreviewViewController *)viewController;
 
-     [viewController.view addGestureRecognizer:self.panGesture];
 
- }
 
- - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
 
-     return !self.vc.collectionView.isDragging;
 
- }
 
- - (void)gestureRecognizeDidUpdate:(UIPanGestureRecognizer *)gestureRecognizer {
 
-     if (self.isFinished) {
 
-         return;
 
-     }
 
-     BOOL isTracking = NO;
 
-     HXPhotoPreviewViewCell *cell = [self.vc currentPreviewCell];
 
-     CGRect toRect = [cell.previewContentView convertRect:cell.previewContentView.bounds toView:cell.scrollView];
 
-     if ((cell.scrollView.isZooming || cell.scrollView.contentOffset.y > 0 || cell.scrollView.isZoomBouncing || !cell.allowInteration || (toRect.origin.x != 0 && cell.previewContentView.hx_w > cell.scrollView.hx_w)) && !self.interation) {
 
-         return;
 
-     }else {
 
-         isTracking = cell.scrollView.isTracking;
 
-     }
 
-     switch (gestureRecognizer.state) {
 
-         case UIGestureRecognizerStateBegan: {
 
-             [self panGestureBegan:gestureRecognizer];
 
-         }   break;
 
-         case UIGestureRecognizerStateChanged:
 
-             if (!self.interation || !self.beginInterPercentCompletion) {
 
-                 if (isTracking) {
 
-                     [self panGestureBegan:gestureRecognizer];
 
-                     if (self.interation) {
 
-                         self.slidingGap = [gestureRecognizer translationInView:gestureRecognizer.view];
 
-                     }
 
-                 }
 
-                 return;
 
-             }
 
-             [self panGestureChanged:gestureRecognizer];
 
-             break;
 
-         case UIGestureRecognizerStateEnded:
 
-             self.startPop = NO;
 
-             [self panGestureEnd:gestureRecognizer];
 
-             self.slidingGap = CGPointZero;
 
-             break;
 
-         default:
 
-             self.startPop = NO;
 
-             [self panGestureOther:gestureRecognizer];
 
-             self.slidingGap = CGPointZero;
 
-             break;
 
-     }
 
- }
 
- - (CGFloat)panGestureScale:(UIPanGestureRecognizer *)panGesture {
 
-     CGPoint translation = [panGesture translationInView:panGesture.view];
 
-     CGFloat transitionY = translation.y;
 
-     CGFloat scale = (transitionY - self.slidingGap.y) / ((panGesture.view.frame.size.height - 50) / 2);
 
-     if (scale > 1.f) {
 
-         scale = 1.f;
 
-     }
 
-     return scale;
 
- }
 
- - (void)panGestureBegan:(UIPanGestureRecognizer *)panGesture {
 
-     if (self.interation || self.beginInterPercentCompletion || self.startPop) {
 
-         return;
 
-     }
 
-     HXPhotoPreviewViewController *previewVC = (HXPhotoPreviewViewController *)self.vc;
 
-     CGPoint velocity = [panGesture velocityInView:previewVC.view];
 
-     BOOL isVerticalGesture = (fabs(velocity.y) > fabs(velocity.x) && velocity.y > 0);
 
-     if (!isVerticalGesture) {
 
-         return;
 
-     }
 
-     [previewVC setStopCancel:YES];
 
-     self.beginX = [panGesture locationInView:panGesture.view].x;
 
-     self.beginY = [panGesture locationInView:panGesture.view].y;
 
-     self.interation = YES;
 
-     self.beginInterPercentCompletion = NO;
 
-     self.startPop = YES;
 
-     [self.vc.navigationController popViewControllerAnimated:YES];
 
- }
 
- - (void)panGestureChanged:(UIPanGestureRecognizer *)panGesture {
 
-     if (self.interation && self.beginInterPercentCompletion) {
 
-         CGFloat scale = [self panGestureScale:panGesture];
 
-         if (scale < 0.f) {
 
-             scale = 0.f;
 
-         }
 
-         CGPoint translation = [panGesture translationInView:panGesture.view];
 
-         CGFloat imageViewScale = 1 - scale * 0.5;
 
-         if (imageViewScale < 0.4) {
 
-             imageViewScale = 0.4;
 
-         }
 
-         self.fromCell.center = CGPointMake(self.transitionImgViewCenter.x + (translation.x - self.slidingGap.x), self.transitionImgViewCenter.y + (translation.y - self.slidingGap.y));
 
-         self.fromCell.transform = CGAffineTransformMakeScale(imageViewScale, imageViewScale);
 
-         
 
-         [self updateInterPercent:1 - scale * scale];
 
-         
 
-         [self updateInteractiveTransition:scale];
 
-     }
 
- }
 
- - (void)panGestureEnd:(UIPanGestureRecognizer *)panGesture {
 
-     
 
-     if (self.interation) {
 
-         CGFloat scale = [self panGestureScale:panGesture];
 
-         if (scale < 0.f) {
 
-             scale = 0.f;
 
-         }
 
-         if (scale < 0.15f){
 
-             [self cancelInteractiveTransition];
 
-             [self interPercentCancel];
 
-         }else {
 
-             self.isFinished = YES;
 
-             [self finishInteractiveTransition];
 
-             [self interPercentFinish];
 
-         }
 
-     }
 
- }
 
- - (void)panGestureOther:(UIPanGestureRecognizer *)panGesture {
 
-     self.vc.view.userInteractionEnabled = YES;
 
-     if (self.interation) {
 
-         [self cancelInteractiveTransition];
 
-         [self interPercentCancel];
 
-     }
 
- }
 
- - (void)beginInterPercent {
 
-     id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
 
-     
 
-     HXPhotoPreviewViewController *fromVC = (HXPhotoPreviewViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
 
-     
 
-     HXPhotoViewController *toVC = (HXPhotoViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
 
-     UIView *containerView = [transitionContext containerView];
 
-     [containerView addSubview:toVC.view];
 
-     [containerView addSubview:fromVC.view];
 
-     if (!self.startPop) {
 
-         self.interation = NO;
 
-         [self.vc.view removeGestureRecognizer:self.panGesture];
 
-         self.isFinished = YES;
 
-         [self cancelInteractiveTransition];
 
-         NSTimeInterval duration = fromVC.manager.configuration.popInteractiveTransitionDuration;
 
-         UIViewAnimationOptions option = UIViewAnimationOptionLayoutSubviews;
 
-         [UIView animateWithDuration:duration delay:0 options:option animations:^{
 
-         } completion:^(BOOL finished) {
 
-             [self.transitionContext completeTransition:NO];
 
-             self.isFinished = NO;
 
-             [self.vc.view addGestureRecognizer:self.panGesture];
 
-         }];
 
-         return;
 
-     }
 
-     HXPhotoModel *model = [fromVC.modelArray objectAtIndex:fromVC.currentModelIndex];
 
-     HXPhotoPreviewViewCell *fromCell = [fromVC currentPreviewCell:model];
 
-     HXPhotoViewCell *toCell = [toVC currentPreviewCell:model];
 
-     self.fromCell = fromCell;
 
-     CGRect tempImageViewFrame;
 
-     self.imageInitialFrame = fromCell.frame;
 
-     tempImageViewFrame = [fromCell convertRect:fromCell.bounds toView:containerView];
 
-     if (!toCell) {
 
-         [toVC scrollToModel:model];
 
-         toCell = [toVC currentPreviewCell:model];
 
-     }
 
-     self.bgView = [[UIView alloc] initWithFrame:containerView.bounds];
 
-     self.bgView.backgroundColor = [HXPhotoCommon photoCommon].isDark ? [UIColor blackColor] : fromVC.manager.configuration.previewPhotoViewBgColor;
 
-     CGFloat scaleX;
 
-     CGFloat scaleY;
 
-     if (self.beginX < tempImageViewFrame.origin.x) {
 
-         scaleX = 0;
 
-     }else if (self.beginX > CGRectGetMaxX(tempImageViewFrame)) {
 
-         scaleX = 1.0f;
 
-     }else {
 
-         scaleX = (self.beginX - tempImageViewFrame.origin.x) / tempImageViewFrame.size.width;
 
-     }
 
-     if (self.beginY < tempImageViewFrame.origin.y) {
 
-         scaleY = 0;
 
-     }else if (self.beginY > CGRectGetMaxY(tempImageViewFrame)){
 
-         scaleY = 1.0f;
 
-     }else {
 
-         scaleY = (self.beginY - tempImageViewFrame.origin.y) / tempImageViewFrame.size.height;
 
-     }
 
-     self.fromCell.layer.anchorPoint = CGPointMake(scaleX, scaleY);
 
-     self.fromCell.frame = tempImageViewFrame;
 
-     self.transitionImgViewCenter = self.fromCell.center;
 
-     [toVC.view insertSubview:self.bgView belowSubview:toVC.bottomView];
 
-     [toVC.view insertSubview:self.fromCell belowSubview:toVC.bottomView];
 
-     if (!fromVC.bottomView.userInteractionEnabled) {
 
-         self.bgView.backgroundColor = [UIColor blackColor];
 
- #pragma clang diagnostic push
 
- #pragma clang diagnostic ignored"-Wdeprecated-declarations"
 
-         [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
 
- #pragma clang diagnostic pop
 
-         
 
-         if (HX_IOS11_Later) {
 
-             // 处理 ios11 当导航栏隐藏时手势返回的问题
 
-             [toVC.navigationController.navigationBar.layer removeAllAnimations];
 
-             // 找到动画异常的视图,然后移除layer动画 !!!!!
 
-             // 一层一层的慢慢的找,把每个有动画的全部移除
 
-             [self removeAllAnimationsForView:toVC.navigationController.navigationBar];
 
-             [toVC.navigationController setNavigationBarHidden:NO animated:YES];
 
-         }else {
 
-             [toVC.navigationController setNavigationBarHidden:NO];
 
-         }
 
-         toVC.navigationController.navigationBar.alpha = 0;
 
-         toVC.bottomView.alpha = 0;
 
-         toVC.limitView.alpha = 0;
 
-     }else {
 
-         toVC.limitView.alpha = 1;
 
-         toVC.bottomView.alpha = 1;
 
-         self.bgView.backgroundColor = [HXPhotoCommon photoCommon].isDark ? [UIColor blackColor] : fromVC.manager.configuration.previewPhotoViewBgColor;
 
-     }
 
- //    toVC.navigationController.navigationBar.userInteractionEnabled = NO;
 
-     self.toVC = toVC;
 
-     fromVC.collectionView.hidden = YES;
 
-     toCell.hidden = YES;
 
-     fromVC.view.backgroundColor = [UIColor clearColor];
 
-     
 
-     CGRect rect = [toCell.imageView convertRect:toCell.imageView.bounds toView: containerView];
 
-     if (toCell) {
 
-         [toVC scrollToPoint:toCell rect:rect];
 
-     }
 
-     self.tempCell = toCell;
 
-     if (self.fromCell.previewContentView.model.subType == HXPhotoModelMediaSubTypeVideo) {
 
-         [self.fromCell.previewContentView.videoView hideOtherView:YES];
 
-     }
 
-     [self resetScrollView:NO];
 
-     self.beginInterPercentCompletion = YES;
 
- }
 
- - (void)removeAllAnimationsForView:(UIView *)view {
 
-     for (UIView *navBarView in view.subviews) {
 
-         [navBarView.layer removeAllAnimations];
 
-         for (UIView *navBarSubView in navBarView.subviews) {
 
-             [navBarSubView.layer removeAllAnimations];
 
-             for (UIView *backView in navBarSubView.subviews) {
 
-                 [backView.layer removeAllAnimations];
 
-                 for (UIView *backSubView in backView.subviews) {
 
-                     [backSubView.layer removeAllAnimations];
 
-                     for (UIView *backSSubView in backSubView.subviews) {
 
-                         [backSSubView.layer removeAllAnimations];
 
-                         for (CALayer *subLayer in backSSubView.layer.sublayers) {
 
-                             // !!!!!!!!
 
-                             [subLayer removeAllAnimations];
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-     }
 
- }
 
- - (void)updateInterPercent:(CGFloat)scale{
 
-     HXPhotoPreviewViewController *fromVC = (HXPhotoPreviewViewController *)[self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
 
-     fromVC.view.alpha = scale;
 
-     self.bgView.alpha = fromVC.view.alpha;
 
-     
 
-     if (!fromVC.bottomView.userInteractionEnabled) {
 
-         HXPhotoViewController *toVC = (HXPhotoViewController *)[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
 
-         toVC.bottomView.alpha = 1 - scale;
 
-         toVC.limitView.alpha = 1 - scale;
 
-         toVC.navigationController.navigationBar.alpha = 1 - scale;
 
-     }
 
- }
 
- - (void)interPercentCancel{
 
-     id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
 
-     HXPhotoPreviewViewController *fromVC = (HXPhotoPreviewViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
 
-     HXPhotoViewController *toVC = (HXPhotoViewController *)[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
 
-     if (!fromVC.bottomView.userInteractionEnabled) {
 
- #pragma clang diagnostic push
 
- #pragma clang diagnostic ignored"-Wdeprecated-declarations"
 
-         [[UIApplication sharedApplication] setStatusBarHidden:YES];
 
- #pragma clang diagnostic pop
 
-         [toVC.navigationController setNavigationBarHidden:YES];
 
-         toVC.navigationController.navigationBar.alpha = 1;
 
-     }
 
-     if (self.fromCell.previewContentView.model.subType == HXPhotoModelMediaSubTypeVideo) {
 
-         [self.fromCell.previewContentView.videoView showOtherView];
 
-     }
 
-     self.panGesture.enabled = NO;
 
-     [UIView animateWithDuration:0.2f animations:^{
 
-         fromVC.view.alpha = 1;
 
-         self.fromCell.transform = CGAffineTransformIdentity;
 
-         self.fromCell.center = self.transitionImgViewCenter;
 
-         self.bgView.alpha = 1;
 
-         if (!fromVC.bottomView.userInteractionEnabled) {
 
-             toVC.bottomView.alpha = 0;
 
-             toVC.limitView.alpha = 0;
 
-         }else {
 
-             toVC.bottomView.alpha = 1;
 
-             toVC.limitView.alpha = 1;
 
-         }
 
-     } completion:^(BOOL finished) {
 
- //        toVC.navigationController.navigationBar.userInteractionEnabled = YES;
 
-         if (finished) {
 
-             fromVC.collectionView.hidden = NO;
 
-             if (!fromVC.bottomView.userInteractionEnabled) {
 
-                 fromVC.view.backgroundColor = [UIColor blackColor];
 
-                 if (HX_IOS11_Later) {
 
-                     // 处理 ios11 当导航栏隐藏时手势返回的问题
 
-                     [toVC.navigationController setNavigationBarHidden:YES];
 
-                 }
 
-             }else {
 
-                 fromVC.view.backgroundColor = [HXPhotoCommon photoCommon].isDark ? [UIColor blackColor] : fromVC.manager.configuration.previewPhotoViewBgColor;
 
-             }
 
-             self.tempCell.hidden = NO;
 
-             self.tempCell = nil;
 
-             [self resetScrollView:YES];
 
-             self.fromCell.layer.anchorPoint = CGPointMake(0.5f, 0.5f);
 
-             self.fromCell.frame = self.imageInitialFrame;
 
-             [fromVC.collectionView addSubview:self.fromCell];
 
-             [self.bgView removeFromSuperview];
 
-             self.bgView = nil;
 
-             self.fromCell = nil;
 
-             self.toVC = nil;
 
-             [self.transitionContext completeTransition:NO];
 
-             self.transitionContext = nil;
 
-             dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 
-                 self.panGesture.enabled = YES;
 
-             });
 
-             self.interation = NO;
 
-             self.beginInterPercentCompletion = NO;
 
-         }
 
-     }];
 
- }
 
- //完成
 
- - (void)interPercentFinish {
 
-     id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
 
-     UIView *containerView = [transitionContext containerView];
 
-     HXPhotoPreviewViewController *fromVC = (HXPhotoPreviewViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
 
-     HXPhotoViewController *toVC = (HXPhotoViewController *)[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
 
-     NSTimeInterval duration = fromVC.manager.configuration.popInteractiveTransitionDuration;
 
-     UIViewAnimationOptions option = UIViewAnimationOptionLayoutSubviews;
 
-     
 
-     if (self.fromCell.previewContentView.model.subType == HXPhotoModelMediaSubTypeVideo) {
 
-         [self.fromCell.previewContentView.videoView hideOtherView:NO];
 
-     }
 
-     CGRect toRect = [self.tempCell convertRect:self.tempCell.bounds toView:containerView];
 
-     [UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:0.8 initialSpringVelocity:0.1 options:option animations:^{
 
-         if (self.tempCell) {
 
-             self.fromCell.transform = CGAffineTransformIdentity;
 
-             self.fromCell.frame = toRect;
 
-             self.fromCell.scrollView.contentOffset = CGPointZero;
 
-             self.fromCell.previewContentView.frame = CGRectMake(0, 0, toRect.size.width, toRect.size.height);
 
-         }else {
 
-             self.fromCell.center = self.transitionImgViewCenter;
 
-             self.fromCell.alpha = 0;
 
-             self.fromCell.transform = CGAffineTransformMakeScale(0.3, 0.3);
 
-         }
 
-         fromVC.view.alpha = 0;
 
-         self.bgView.alpha = 0;
 
-         toVC.navigationController.navigationBar.alpha = 1;
 
-         toVC.bottomView.alpha = 1;
 
-         toVC.limitView.alpha = 1;
 
-     }completion:^(BOOL finished) {
 
- //        toVC.navigationController.navigationBar.userInteractionEnabled = YES;
 
-         if (finished) {
 
-             if (!fromVC.bottomView.userInteractionEnabled && HX_IOS11_Later) {
 
-                 // 处理 ios11 当导航栏隐藏时手势返回的问题
 
-                 [toVC.navigationController.navigationBar.layer removeAllAnimations];
 
-                 [toVC.navigationController setNavigationBarHidden:NO];
 
-             }
 
-             [self.tempCell bottomViewPrepareAnimation];
 
-             self.tempCell.hidden = NO;
 
-             [self.tempCell bottomViewStartAnimation];
 
-             
 
-             [self.fromCell.previewContentView cancelRequest];
 
-             [self.fromCell removeFromSuperview];
 
-             [self.bgView removeFromSuperview];
 
-             self.fromCell = nil;
 
-             self.toVC = nil;
 
-             [self.transitionContext completeTransition:YES];
 
-             self.transitionContext = nil;
 
-         }
 
-         self.interation = NO;
 
-         self.beginInterPercentCompletion = NO;
 
-     }];  
 
- }
 
- - (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
 
-     self.transitionContext = transitionContext;
 
-     [self beginInterPercent];
 
- }
 
- - (void)resetScrollView:(BOOL)enabled {
 
-     id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
 
-     HXPhotoPreviewViewController *fromVC = (HXPhotoPreviewViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
 
-     fromVC.collectionView.scrollEnabled = enabled;
 
-     self.fromCell.scrollView.scrollEnabled = enabled;
 
-     self.fromCell.scrollView.pinchGestureRecognizer.enabled = enabled;
 
-     self.fromCell.scrollView.clipsToBounds = enabled;
 
- }
 
- @end
 
 
  |