Send onScrollEnded Event to native driver (#45382)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45382

This change is the first step to tr and solve the pressability's `onTouchMove` issue with animation driven natively in the New Architecture.

 The idea is to trigger a special event from native to let JS know that a scroll event has ended (`scrollViewDidEndDragging` or `scrollViewdidEndDecelerating`).

When this happens, we need to send an event to JS to let him know that it has to sync the Native Tree with the Shadow Tree.

Step 2 is to connect Native with JS

## Changelog:
[iOS][Added] - Send onScrollEnded event to NativeTurboAnimatedModule

Reviewed By: sammy-SC

Differential Revision: D59459989

fbshipit-source-id: cb425cddcdaa9d700ec40accaf4ab3ce1f3c5038
This commit is contained in:
Riccardo Cipolleschi
2024-07-17 09:22:39 -07:00
committed by Facebook GitHub Bot
parent dbbb4069b9
commit 7af743236f
2 changed files with 20 additions and 3 deletions
@@ -368,6 +368,15 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
[drivers addObject:driver];
_eventDrivers[key] = drivers;
}
// Handle onScrollEnded special events.
// These are triggered when the user stops dragging or when the
// scroll view stops decelerating after the user swiped
// The goal is to use this event to force a resync of the Shadow Tree
// with the Native tree
if ([eventName isEqualToString:@"onScroll"]) {
[self addAnimatedEventToView:viewTag eventName:@"onScrollEnded" eventMapping:eventMapping];
}
}
- (void)removeAnimatedEventFromView:(NSNumber *)viewTag
@@ -26,6 +26,10 @@
using namespace facebook::react;
static NSString *kOnScrollEvent = @"onScroll";
static NSString *kOnScrollEndEvent = @"onScrollEnded";
static const CGFloat kClippingLeeway = 44.0;
static UIScrollViewKeyboardDismissMode RCTUIKeyboardDismissModeFromProps(const ScrollViewProps &props)
@@ -56,10 +60,11 @@ static UIScrollViewIndicatorStyle RCTUIScrollViewIndicatorStyleFromProps(const S
// This is just a workaround to allow animations based on onScroll event.
// This is only used to animate sticky headers in ScrollViews, and only the contentOffset and tag is used.
// TODO: T116850910 [Fabric][iOS] Make Fabric not use legacy RCTEventDispatcher for native-driven AnimatedEvents
static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInteger tag)
static void
RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInteger tag, NSString *eventName)
{
static uint16_t coalescingKey = 0;
RCTScrollEvent *scrollEvent = [[RCTScrollEvent alloc] initWithEventName:@"onScroll"
RCTScrollEvent *scrollEvent = [[RCTScrollEvent alloc] initWithEventName:eventName
reactTag:[NSNumber numberWithInt:tag]
scrollViewContentOffset:scrollView.contentOffset
scrollViewContentInset:scrollView.contentInset
@@ -507,7 +512,7 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScroll(scrollMetrics);
}
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag);
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent);
}
}
@@ -564,6 +569,7 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
// ScrollView will not decelerate and `scrollViewDidEndDecelerating` will not be called.
// `_isUserTriggeredScrolling` must be set to NO here.
_isUserTriggeredScrolling = NO;
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEndEvent);
}
}
@@ -589,6 +595,8 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onMomentumScrollEnd([self _scrollViewMetrics]);
[self _updateStateWithContentOffset];
_isUserTriggeredScrolling = NO;
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEndEvent);
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView