Fix sticky headers for scrollviews by sending onScroll event to legacy RCTEventDispatcher

Summary:
Changelog: [Internal][Bridgeless] Fix sticky headers for scrollviews by sending onScroll event to legacy RCTEventDispatcher

## Extra Context

FYI. <ScrollView> is the only Fabric component view that needs to send events via the legacy RCTEventDispatcher. Ideally, all component views should only use `ViewEventEmitter` to send events to JS and not use RCTEventDispatcher. This ScrollView does use ScrollViewEventEmitter, a subclass of ViewEventEmitter:
```
std::static_pointer_cast<ScrollViewEventEmitter const>(_eventEmitter)->onScroll([self _scrollViewMetrics]);
```

However, it also needs RCTEventDispatcher for animations using `Animated.event` for `useNativeDriver: true`. See [ScrollView.js](https://github.com/facebook/react-native/blob/370c65b94379a72e74f5dfd5b6202f282841a950/Libraries/Components/ScrollView/ScrollView.js#L1124-L1129).

Reviewed By: RSNara

Differential Revision: D35540277

fbshipit-source-id: a28535ed10cac8e003523ecda6080574fbb89b85
This commit is contained in:
Paige Sun
2022-04-11 15:30:14 -07:00
committed by Facebook GitHub Bot
parent f503b21203
commit c032401b67
@@ -52,7 +52,11 @@ static UIScrollViewIndicatorStyle RCTUIScrollViewIndicatorStyleFromProps(ScrollV
}
}
static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteger tag)
// Once Fabric implements proper NativeAnimationDriver, this should be removed.
// 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 uint16_t coalescingKey = 0;
RCTScrollEvent *scrollEvent = [[RCTScrollEvent alloc] initWithEventName:@"onScroll"
@@ -64,7 +68,15 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg
scrollViewZoomScale:scrollView.zoomScale
userData:nil
coalescingKey:coalescingKey];
[[RCTBridge currentBridge].eventDispatcher sendEvent:scrollEvent];
RCTBridge *bridge = [RCTBridge currentBridge];
if (bridge) {
[bridge.eventDispatcher sendEvent:scrollEvent];
} else {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:scrollEvent, @"event", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"RCTSendEventToLegacyEventDispatcher"
object:nil
userInfo:userInfo];
}
}
@interface RCTScrollViewComponentView () <
@@ -403,9 +415,8 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg
if (_eventEmitter) {
std::static_pointer_cast<ScrollViewEventEmitter const>(_eventEmitter)->onScroll([self _scrollViewMetrics]);
}
// Once Fabric implements proper NativeAnimationDriver, this should be removed.
// This is just a workaround to allow animations based on onScroll event.
RCTSendPaperScrollEvent_DEPRECATED(scrollView, self.tag);
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag);
}
[self _remountChildrenIfNeeded];