react-native-navigation的迁移库

RNNInteractivePopAnimator.m 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #import "RNNInteractivePopAnimator.h"
  2. #import "RNNAnimator.h"
  3. #import "RNNAnimatedView.h"
  4. #import "RNNElementView.h"
  5. #import "RNNRootViewController.h"
  6. #import "VICMAImageView.h"
  7. @interface RNNInteractivePopAnimator()
  8. @property (nonatomic) CGRect topFrame;
  9. @property (nonatomic) CGFloat percent;
  10. @property (nonatomic) UINavigationController* nc;
  11. @property (nonatomic) UIView* imageSnapshot;
  12. @property (nonatomic) double totalTranslate;
  13. @property (nonatomic) id transitionContext;
  14. @end
  15. @implementation RNNInteractivePopAnimator
  16. -(instancetype)initWithTopView:(RNNElementView*)topView andBottomView:(RNNElementView*)bottomView andOriginFrame:(CGRect)originFrame andViewController:(UIViewController*)vc{
  17. RNNInteractivePopAnimator* interactiveController = [[RNNInteractivePopAnimator alloc] init];
  18. [interactiveController setTopView:topView];
  19. [interactiveController setBottomView:bottomView];
  20. [interactiveController setOriginFrame:originFrame];
  21. [interactiveController setVc:vc];
  22. [interactiveController setNc:vc.navigationController];
  23. return interactiveController;
  24. }
  25. -(void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
  26. [super startInteractiveTransition:transitionContext];
  27. }
  28. -(BOOL)shouldBeginInteractivePop:(CGPoint)velocity {
  29. if (velocity.y > 0) {
  30. return YES;
  31. }
  32. return NO;
  33. }
  34. -(BOOL)shouldCancelInteractivePop:(UIPanGestureRecognizer*)recognizer {
  35. return ([recognizer velocityInView:self.imageSnapshot].y < 0 || self.totalTranslate < 0);
  36. }
  37. -(void)handleGesture:(UIPanGestureRecognizer*)recognizer {
  38. CGPoint translation = [recognizer translationInView:self.topView];
  39. if (recognizer.state == UIGestureRecognizerStateBegan) {
  40. CGPoint velocity = [recognizer velocityInView:recognizer.view];
  41. self.nc.delegate = self;
  42. if ([self shouldBeginInteractivePop:velocity]) {
  43. [self.nc popViewControllerAnimated:YES];
  44. }
  45. } else
  46. if (recognizer.state == UIGestureRecognizerStateChanged) {
  47. self.totalTranslate = self.totalTranslate + translation.y;
  48. [self animateAlongsideTransition:^void(id context){
  49. self.imageSnapshot.center = CGPointMake(self.imageSnapshot.center.x + translation.x,
  50. self.imageSnapshot.center.y + translation.y);
  51. }
  52. completion:nil];
  53. [recognizer setTranslation:CGPointMake(0, 0) inView:self.imageSnapshot];
  54. if (self.totalTranslate >= 0 && self.totalTranslate <= 400.0) {
  55. [self updateInteractiveTransition:self.totalTranslate/400];
  56. }
  57. } else if (recognizer.state == UIGestureRecognizerStateEnded) {
  58. if([self shouldCancelInteractivePop:recognizer]) {
  59. [self cancelInteractiveTransition];
  60. [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
  61. self.imageSnapshot.frame = self.topFrame;
  62. } completion:^(BOOL finished) {
  63. self.nc.delegate = (RNNRootViewController*)self.vc;
  64. }];
  65. } else {
  66. [UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
  67. self.imageSnapshot.frame = self.originFrame;
  68. self.imageSnapshot.contentMode = UIViewContentModeScaleAspectFill;
  69. if ([self.bottomView resizeMode]) {
  70. self.imageSnapshot.contentMode = [RNNAnimatedView contentModefromString:[self.bottomView resizeMode]];
  71. }
  72. } completion:^(BOOL finished) {
  73. self.nc.delegate = nil;
  74. }];
  75. [self finishInteractiveTransition];
  76. }
  77. }
  78. }
  79. - (BOOL)animateAlongsideTransition:(void (^)(id<UIViewControllerTransitionCoordinatorContext> context))animation
  80. completion:(void (^)(id<UIViewControllerTransitionCoordinatorContext> context))completion;{
  81. animation(nil);
  82. return YES;
  83. }
  84. - (void)animationEnded:(BOOL)transitionCompleted {
  85. }
  86. - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
  87. {
  88. return 0.7;
  89. }
  90. - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
  91. {
  92. self.totalTranslate = 0;
  93. self.transitionContext = transitionContext;
  94. UIViewController* toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
  95. UIViewController* fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  96. UIView* componentView = [transitionContext containerView];
  97. toVC.view.frame = fromVC.view.frame;
  98. UIView* topViewContent = [self.topView subviews][0];
  99. UIImage* image = [[self.topView subviews][0] image];
  100. UIView* imageSnapshot = [[VICMAImageView alloc] initWithImage:image];
  101. CGPoint fromSharedViewFrameOrigin = [topViewContent.superview convertPoint:topViewContent.frame.origin toView:fromVC.view];
  102. CGRect fromOriginRect = CGRectMake(fromSharedViewFrameOrigin.x, fromSharedViewFrameOrigin.y, topViewContent.frame.size.width, topViewContent.frame.size.height);
  103. self.topFrame = fromOriginRect;
  104. imageSnapshot.contentMode = UIViewContentModeScaleAspectFill;
  105. if ([self.topView resizeMode]) {
  106. imageSnapshot.contentMode = [RNNAnimatedView contentModefromString:[self.topView resizeMode]];
  107. }
  108. imageSnapshot.frame = fromOriginRect;
  109. self.imageSnapshot = imageSnapshot;
  110. [self.bottomView setHidden:YES];
  111. UIView* toSnapshot = [toVC.view snapshotViewAfterScreenUpdates:true];
  112. toSnapshot.frame = fromVC.view.frame;
  113. [componentView insertSubview:(UIView *)toSnapshot atIndex:1];
  114. [componentView addSubview:self.imageSnapshot];
  115. toSnapshot.alpha = 0.0;
  116. [self.topView setHidden:YES];
  117. [UIView animateKeyframesWithDuration:(NSTimeInterval)[self transitionDuration:transitionContext]
  118. delay:0
  119. options: UIViewKeyframeAnimationOptionAllowUserInteraction
  120. animations:^{
  121. [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{
  122. fromVC.view.alpha = 0;
  123. toSnapshot.alpha = 1;
  124. }];
  125. }
  126. completion:^(BOOL finished) {
  127. [self.bottomView setHidden:NO];
  128. [toSnapshot removeFromSuperview];
  129. [self.imageSnapshot removeFromSuperview];
  130. self.totalTranslate = 0;
  131. if (![transitionContext transitionWasCancelled]) {
  132. [componentView addSubview: toVC.view];
  133. [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  134. }
  135. if ([transitionContext transitionWasCancelled]) {
  136. [self.topView setHidden:NO];
  137. [componentView addSubview: fromVC.view];
  138. [transitionContext completeTransition:NO];
  139. }
  140. }];
  141. }
  142. - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
  143. animationControllerForOperation:(UINavigationControllerOperation)operation
  144. fromViewController:(UIViewController*)fromVC
  145. toViewController:(UIViewController*)toVC {
  146. if (operation == UINavigationControllerOperationPop) {
  147. return self;
  148. } else {
  149. return nil;
  150. }
  151. return nil;
  152. }
  153. - (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
  154. interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController {
  155. return self;
  156. }
  157. @end