From 39b599fde70360b6ed0ecbaa19b280ff08e585e9 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 30 Oct 2024 00:52:11 +0100 Subject: [PATCH] Playaround with implementation of simple push --- ios/RNSScreenStackAnimator.mm | 88 +++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/ios/RNSScreenStackAnimator.mm b/ios/RNSScreenStackAnimator.mm index d49d964e06..20741b60a2 100644 --- a/ios/RNSScreenStackAnimator.mm +++ b/ios/RNSScreenStackAnimator.mm @@ -13,6 +13,9 @@ // and it looks the most similar to the value used by Apple static constexpr float RNSShadowViewMaxAlpha = 0.1; static const int UIViewAnimationOptionCurveDefaultTransition = 7 << 16; +// static constexpr UIViewAnimationOptions RNSUIViewAnimationOptionsCommon = UIViewAnimationOptionCurveEaseInOut; +static constexpr UIViewAnimationOptions RNSUIViewAnimationOptionsCommon = 7 << 16; +// static constexpr UIViewAnimationOptions RNSUIViewAnimationOptionsCommon = UIViewAnimationOptionCurveLinear; @implementation RNSScreenStackAnimator { UINavigationControllerOperation _operation; @@ -129,24 +132,33 @@ - (void)animateSimplePushWithShadowEnabled:(BOOL)shadowEnabled shadowView.alpha = 0.0; } - [UIView animateWithDuration:[self transitionDuration:transitionContext] - delay:0 - options:UIViewAnimationOptionCurveDefaultTransition - animations:^{ - fromViewController.view.transform = leftTransform; - toViewController.view.transform = CGAffineTransformIdentity; - if (shadowView) { - shadowView.alpha = RNSShadowViewMaxAlpha; - } - } - completion:^(BOOL finished) { - if (shadowView) { - [shadowView removeFromSuperview]; - } - fromViewController.view.transform = CGAffineTransformIdentity; - toViewController.view.transform = CGAffineTransformIdentity; - [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; - }]; + // Default curve provider is as defined below, however defined this way it ignores the `animationDuration` prop. + // Damping of 1.0 seems close enough. + // id timingCurveProvider = [[UISpringTimingParameters alloc] init]; + + id timingCurveProvider = [[UISpringTimingParameters alloc] initWithDampingRatio:1.0]; + + UIViewPropertyAnimator *animator = + [[UIViewPropertyAnimator alloc] initWithDuration:[self transitionDuration:transitionContext] + timingParameters:timingCurveProvider]; + + [animator addAnimations:^{ + fromViewController.view.transform = leftTransform; + toViewController.view.transform = CGAffineTransformIdentity; + if (shadowView) { + shadowView.alpha = RNSShadowViewMaxAlpha; + } + }]; + + [animator addCompletion:^(UIViewAnimatingPosition finalPosition) { + if (shadowView) { + [shadowView removeFromSuperview]; + } + fromViewController.view.transform = CGAffineTransformIdentity; + toViewController.view.transform = CGAffineTransformIdentity; + [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; + }]; + [animator startAnimation]; } else if (_operation == UINavigationControllerOperationPop) { toViewController.view.transform = leftTransform; [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view]; @@ -162,7 +174,7 @@ - (void)animateSimplePushWithShadowEnabled:(BOOL)shadowEnabled shadowView.alpha = 0.0; } }; - void (^completionBlock)(BOOL) = ^(BOOL finished) { + void (^completionBlock)(UIViewAnimatingPosition) = ^(UIViewAnimatingPosition finalPosition) { if (shadowView) { [shadowView removeFromSuperview]; } @@ -172,18 +184,24 @@ - (void)animateSimplePushWithShadowEnabled:(BOOL)shadowEnabled }; if (!transitionContext.isInteractive) { - [UIView animateWithDuration:[self transitionDuration:transitionContext] - delay:0 - options:UIViewAnimationOptionCurveDefaultTransition - animations:animationBlock - completion:completionBlock]; + id timingCurveProvider = [[UISpringTimingParameters alloc] initWithDampingRatio:1.0]; + + UIViewPropertyAnimator *animator = + [[UIViewPropertyAnimator alloc] initWithDuration:[self transitionDuration:transitionContext] + timingParameters:timingCurveProvider]; + + [animator addAnimations:animationBlock]; + [animator addCompletion:completionBlock]; + [animator startAnimation]; } else { // we don't want the EaseInOut option when swiping to dismiss the view, it is the same in default animation option - [UIView animateWithDuration:[self transitionDuration:transitionContext] - delay:0.0 - options:UIViewAnimationOptionCurveLinear - animations:animationBlock - completion:completionBlock]; + UIViewPropertyAnimator *animator = + [[UIViewPropertyAnimator alloc] initWithDuration:[self transitionDuration:transitionContext] + curve:UIViewAnimationCurveLinear + animations:animationBlock]; + + [animator addCompletion:completionBlock]; + [animator startAnimation]; } } } @@ -209,7 +227,7 @@ - (void)animateSlideFromLeftWithTransitionContext:(id