From b69c283ce9da380eb91fdcd30af95fcfb77cbac1 Mon Sep 17 00:00:00 2001 From: Genki Kondo Date: Wed, 14 Jun 2023 11:20:24 -0700 Subject: [PATCH] Return final animation values to JS when animation completes (#37886) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37886 When using the native driver for animations that involve layout changes (ie. translateY and other transforms, but not styles such as opacity), because it bypasses Fabric, the new coordinates are not updated so the Pressability responder region/tap target is incorrect **This diff:** - Returning the final values from the native side, at the same place it sets the "finished" flag. This gets sent to JS in `animated/animations/Animation.js`. Changelog: [iOS][Changed] - return animated values to JS for natively driven animations Reviewed By: rshest Differential Revision: D46709214 fbshipit-source-id: 00e149cde4c17d76609aa3c3d29e8747d6d16d10 --- .../Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m | 4 ++-- .../Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m | 4 ++-- .../Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m | 4 ++-- .../RNTesterUnitTests/RCTNativeAnimatedNodesManagerTests.m | 6 ++++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m b/packages/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m index 5c19386cd93650..b4aec0c33288fe 100644 --- a/packages/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m +++ b/packages/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m @@ -70,10 +70,10 @@ - (void)startAnimation - (void)stopAnimation { - _valueNode = nil; if (_callback) { - _callback(@[ @{@"finished" : @(_animationHasFinished)} ]); + _callback(@[ @{@"finished" : @(_animationHasFinished), @"value" : @(_valueNode.value)} ]); } + _valueNode = nil; } - (void)stepAnimationWithTime:(NSTimeInterval)currentTime diff --git a/packages/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m b/packages/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m index d2bf4cd618b24c..1de5cb13eb8ffa 100644 --- a/packages/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m +++ b/packages/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m @@ -76,10 +76,10 @@ - (void)startAnimation - (void)stopAnimation { - _valueNode = nil; if (_callback) { - _callback(@[ @{@"finished" : @(_animationHasFinished)} ]); + _callback(@[ @{@"finished" : @(_animationHasFinished), @"value" : @(_valueNode.value)} ]); } + _valueNode = nil; } - (void)stepAnimationWithTime:(NSTimeInterval)currentTime diff --git a/packages/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m b/packages/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m index 232916017607de..640107df09c287 100644 --- a/packages/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m +++ b/packages/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m @@ -96,10 +96,10 @@ - (void)startAnimation - (void)stopAnimation { - _valueNode = nil; if (_callback) { - _callback(@[ @{@"finished" : @(_animationHasFinished)} ]); + _callback(@[ @{@"finished" : @(_animationHasFinished), @"value" : @(_valueNode.value)} ]); } + _valueNode = nil; } - (void)stepAnimationWithTime:(NSTimeInterval)currentTime diff --git a/packages/rn-tester/RNTesterUnitTests/RCTNativeAnimatedNodesManagerTests.m b/packages/rn-tester/RNTesterUnitTests/RCTNativeAnimatedNodesManagerTests.m index 09682c19e9b433..7e0c3fcefdddf6 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTNativeAnimatedNodesManagerTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTNativeAnimatedNodesManagerTests.m @@ -486,7 +486,8 @@ - (void)testAnimationCallbackFinish RCTResponseSenderBlock endCallback = ^(NSArray *response) { endCallbackCalls++; - XCTAssertEqualObjects(response, @[ @{@"finished" : @YES} ]); + NSArray *expected = @[ @{@"finished" : @YES, @"value" : @1} ]; + XCTAssertEqualObjects(response, expected); }; [_nodesManager startAnimatingNode:@1 @@ -714,7 +715,8 @@ - (void)testHandleStoppingAnimation RCTResponseSenderBlock endCallback = ^(NSArray *response) { endCallbackCalled = YES; - XCTAssertEqualObjects(response, @[ @{@"finished" : @NO} ]); + XCTAssertEqual(response.count, 1); + XCTAssertEqualObjects(response[0][@"finished"], @NO); }; [_nodesManager startAnimatingNode:@404