react-native-navigation的迁移库

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #import <React/RCTRedBox.h>
  2. #import "RNNAnimator.h"
  3. #import "RNNElementView.h"
  4. #import "RNNInteractivePopAnimator.h"
  5. #import "VICMAImageView.h"
  6. #import "RNNTransitionStateHolder.h"
  7. #import "RNNElementFinder.h"
  8. #import "RNNViewLocation.h"
  9. #import "RNNAnimatedView.h"
  10. @interface RNNAnimator()
  11. @property (nonatomic, strong)NSArray* animations;
  12. @property (nonatomic)double duration;
  13. @property (nonatomic)double springDamping;
  14. @property (nonatomic)double springVelocity;
  15. @property (nonatomic, strong) RNNInteractivePopAnimator* interactivePopAnimator;
  16. @property (nonatomic) BOOL backButton;
  17. @property (nonatomic, strong) UIViewController* fromVC;
  18. @property (nonatomic, strong) UIViewController* toVC;
  19. @end
  20. @implementation RNNAnimator
  21. -(void)setupTransition:(NSDictionary*)data{
  22. if ([data objectForKey:@"animations"]) {
  23. self.animations= [data objectForKey:@"animations"];
  24. } else {
  25. [[NSException exceptionWithName:NSInvalidArgumentException reason:@"No animations" userInfo:nil] raise];
  26. }
  27. if ([data objectForKey:@"duration"]) {
  28. self.duration = [[data objectForKey:@"duration"] doubleValue];
  29. } else {
  30. self.duration = 0.7;
  31. }
  32. if ([data objectForKey:@"springDamping"]) {
  33. self.springDamping = [[data objectForKey:@"springDamping"] doubleValue];
  34. } else {
  35. self.springDamping = 0.85;
  36. }
  37. if ([data objectForKey:@"springVelocity"]) {
  38. self.springVelocity= [[data objectForKey:@"springVelocity"] doubleValue];
  39. } else {
  40. self.springVelocity = 0.8;
  41. }
  42. self.backButton = false;
  43. }
  44. -(NSArray*)prepareSharedElementTransition:(NSArray*)RNNSharedElementsToVC
  45. andfromVCElements:(NSArray*)RNNSharedElementsFromVC
  46. withContainerView:(UIView*)containerView
  47. {
  48. NSMutableArray* transitions = [NSMutableArray new];
  49. for (NSDictionary* transition in self.animations) {
  50. RNNTransitionStateHolder* transitionStateHolder = [[RNNTransitionStateHolder alloc] initWithTransition:transition];
  51. RNNElementFinder* elementFinder = [[RNNElementFinder alloc] initWithToVC:self.toVC andfromVC:self.fromVC];
  52. [elementFinder findElementsInTransition:transitionStateHolder];
  53. RNNViewLocation* animatedViewLocations = [[RNNViewLocation alloc] initWithTransition:transitionStateHolder andVC:self.fromVC];
  54. RNNAnimatedView* animatedView = [[RNNAnimatedView alloc] initWithTransition:transitionStateHolder andLocation:animatedViewLocations andIsBackButton:self.backButton];
  55. transitionStateHolder.locations = animatedViewLocations;
  56. [containerView addSubview:animatedView];
  57. [containerView bringSubviewToFront:animatedView];
  58. transitionStateHolder.animatedView = animatedView;
  59. [transitions addObject:transitionStateHolder];
  60. if (transitionStateHolder.isSharedElementTransition){
  61. [transitionStateHolder.toElement setHidden: YES];
  62. }
  63. [transitionStateHolder.fromElement setHidden:YES];
  64. }
  65. return transitions;
  66. }
  67. -(void)animateTransitions:(NSArray*)transitions {
  68. for (RNNTransitionStateHolder* transition in transitions ) {
  69. [UIView animateWithDuration:transition.duration delay:transition.startDelay usingSpringWithDamping:transition.springDamping initialSpringVelocity:transition.springVelocity options:UIViewAnimationOptionCurveEaseOut animations:^{
  70. RNNAnimatedView* animatedView = transition.animatedView;
  71. if (!self.backButton) {
  72. [self setAnimatedViewFinalProperties:animatedView toElement:transition.toElement fromElement:transition.fromElement isSharedElementTransition:transition.isSharedElementTransition withTransform:transition.locations.transform withCenter:transition.locations.toCenter andAlpha:transition.endAlpha];
  73. } else {
  74. [self setAnimatedViewFinalProperties:animatedView toElement:transition.fromElement fromElement:transition.fromElement isSharedElementTransition:transition.isSharedElementTransition withTransform:transition.locations.transformBack withCenter:transition.locations.fromCenter andAlpha:transition.startAlpha];
  75. }
  76. } completion:^(BOOL finished) {
  77. }];
  78. }
  79. }
  80. -(void)setAnimatedViewFinalProperties:(RNNAnimatedView*)animatedView toElement:(RNNElementView*)toElement fromElement:(RNNElementView*)fromElement isSharedElementTransition:(BOOL)isShared withTransform:(CGAffineTransform)transform withCenter:(CGPoint)center andAlpha:(double)alpha {
  81. animatedView.alpha = alpha;
  82. animatedView.center = center;
  83. animatedView.transform = transform;
  84. if (isShared) {
  85. if ([[fromElement subviews][0] isKindOfClass:[UIImageView class]]) {
  86. animatedView.contentMode = UIViewContentModeScaleAspectFill;
  87. if ([toElement resizeMode]){
  88. animatedView.contentMode = [RNNAnimatedView contentModefromString:[toElement resizeMode]];
  89. }
  90. }
  91. }
  92. }
  93. -(void)animateComplition:(NSArray*)transitions fromVCSnapshot:(UIView*)fromSnapshot andTransitioningContext:(id<UIViewControllerContextTransitioning>)transitionContext {
  94. [UIView animateWithDuration:[self transitionDuration:transitionContext ] delay:0 usingSpringWithDamping:self.springDamping initialSpringVelocity:self.springVelocity options:UIViewAnimationOptionCurveEaseOut animations:^{
  95. self.toVC.view.alpha = 1;
  96. } completion:^(BOOL finished) {
  97. for (RNNTransitionStateHolder* transition in transitions ) {
  98. [transition.fromElement setHidden:NO];
  99. if (transition.isSharedElementTransition) {
  100. [transition.toElement setHidden:NO];
  101. }
  102. RNNAnimatedView* animtedView = transition.animatedView;
  103. [animtedView removeFromSuperview];
  104. if (transition.interactivePop) {
  105. self.interactivePopAnimator = [[RNNInteractivePopAnimator alloc] initWithTopView:transition.toElement andBottomView:transition.fromElement andOriginFrame:transition.locations.fromFrame andViewController:self.toVC];
  106. UIPanGestureRecognizer* gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopAnimator
  107. action:@selector(handleGesture:)];
  108. [transition.toElement addGestureRecognizer:gesture];
  109. }
  110. }
  111. [fromSnapshot removeFromSuperview];
  112. if (![transitionContext transitionWasCancelled]) {
  113. self.toVC.view.alpha = 1;
  114. [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  115. self.backButton = true;
  116. }
  117. }];
  118. }
  119. - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
  120. {
  121. return self.duration;
  122. }
  123. - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
  124. {
  125. UIViewController* toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
  126. UIViewController* fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  127. UIView* containerView = [transitionContext containerView];
  128. self.fromVC = fromVC;
  129. self.toVC = toVC;
  130. toVC.view.frame = fromVC.view.frame;
  131. UIView* fromSnapshot = [fromVC.view snapshotViewAfterScreenUpdates:true];
  132. fromSnapshot.frame = fromVC.view.frame;
  133. [containerView addSubview:fromSnapshot];
  134. [containerView addSubview:toVC.view];
  135. toVC.view.alpha = 0;
  136. NSArray* onlyForTesting = @[];
  137. NSArray* onlyForTesting2 = @[];
  138. NSArray* transitions = [self prepareSharedElementTransition:onlyForTesting andfromVCElements:onlyForTesting2 withContainerView:containerView];
  139. [self animateComplition:transitions fromVCSnapshot:fromSnapshot andTransitioningContext:transitionContext];
  140. [self animateTransitions:transitions];
  141. }
  142. @end