Skip to content

Commit 083f835

Browse files
janicduplessisfacebook-github-bot
authored andcommitted
Native Animated - Support events using RCT{Direct|Bubbling}EventBlock on iOS (#15611)
Summary: When calling a prop of type `RCTDirectEventBlock` or `RCTBubblingEventBlock` it uses a completely different code path than events using `[RCTEventDispatcher sendEvent:]` and those were not dispatched to the `RCTEventDispatcherListener`s. We also do some event name normalization which caused issues between the JS and native event names. To fix that I simply remove the parts we normalize from the event key. ## Changelog: [iOS] [Fixed] - Support events using RCT{Direct|Bubbling}EventBlock Pull Request resolved: #15611 Test Plan: Added a Slider (it used RCTBubblingEventBlock for it's onValueChange event) that can control a native animated value in RNTester to reproduce the bug and made sure this diff fixes it. Differential Revision: D15896806 Pulled By: cpojer fbshipit-source-id: c0ae463f4c3f890062238575e813ed7ab3b7a7e6
1 parent a89e932 commit 083f835

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@
2828
#import "RCTValueAnimatedNode.h"
2929
#import "RCTTrackingAnimatedNode.h"
3030

31+
// We do some normalizing of the event names in RCTEventDispatcher#RCTNormalizeInputEventName.
32+
// To make things simpler just get rid of the parts we change in the event names we use here.
33+
// This is a lot easier than trying to denormalize because there would be multiple possible
34+
// denormalized forms for a single input.
35+
NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
36+
{
37+
if ([eventName hasPrefix:@"on"]) {
38+
return [eventName substringFromIndex:2];
39+
}
40+
if ([eventName hasPrefix:@"top"]) {
41+
return [eventName substringFromIndex:3];
42+
}
43+
return eventName;
44+
}
45+
3146
@implementation RCTNativeAnimatedNodesManager
3247
{
3348
__weak RCTBridge *_bridge;
@@ -321,7 +336,7 @@ - (void)addAnimatedEventToView:(nonnull NSNumber *)viewTag
321336
RCTEventAnimation *driver =
322337
[[RCTEventAnimation alloc] initWithEventPath:eventPath valueNode:(RCTValueAnimatedNode *)node];
323338

324-
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, eventName];
339+
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, RCTNormalizeAnimatedEventName(eventName)];
325340
if (_eventDrivers[key] != nil) {
326341
[_eventDrivers[key] addObject:driver];
327342
} else {
@@ -335,7 +350,7 @@ - (void)removeAnimatedEventFromView:(nonnull NSNumber *)viewTag
335350
eventName:(nonnull NSString *)eventName
336351
animatedNodeTag:(nonnull NSNumber *)animatedNodeTag
337352
{
338-
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, eventName];
353+
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, RCTNormalizeAnimatedEventName(eventName)];
339354
if (_eventDrivers[key] != nil) {
340355
if (_eventDrivers[key].count == 1) {
341356
[_eventDrivers removeObjectForKey:key];
@@ -357,7 +372,7 @@ - (void)handleAnimatedEvent:(id<RCTEvent>)event
357372
return;
358373
}
359374

360-
NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, event.eventName];
375+
NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, RCTNormalizeAnimatedEventName(event.eventName)];
361376
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
362377
if (driversForKey) {
363378
for (RCTEventAnimation *driver in driversForKey) {

RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ class InternalSettings extends React.Component<
221221

222222
class EventExample extends React.Component<{}, $FlowFixMeState> {
223223
state = {
224-
scrollX: new Animated.Value(0),
224+
anim: new Animated.Value(0),
225225
};
226226

227227
render() {
@@ -233,7 +233,7 @@ class EventExample extends React.Component<{}, $FlowFixMeState> {
233233
{
234234
transform: [
235235
{
236-
rotate: this.state.scrollX.interpolate({
236+
rotate: this.state.anim.interpolate({
237237
inputRange: [0, 1],
238238
outputRange: ['0deg', '1deg'],
239239
}),
@@ -246,7 +246,7 @@ class EventExample extends React.Component<{}, $FlowFixMeState> {
246246
horizontal
247247
style={{height: 100, marginTop: 16}}
248248
onScroll={Animated.event(
249-
[{nativeEvent: {contentOffset: {x: this.state.scrollX}}}],
249+
[{nativeEvent: {contentOffset: {x: this.state.anim}}}],
250250
{useNativeDriver: true},
251251
)}>
252252
<View
@@ -259,6 +259,13 @@ class EventExample extends React.Component<{}, $FlowFixMeState> {
259259
<Text>Scroll me sideways!</Text>
260260
</View>
261261
</Animated.ScrollView>
262+
<AnimatedSlider
263+
maximumValue={200}
264+
onValueChange={Animated.event(
265+
[{nativeEvent: {value: this.state.anim}}],
266+
{useNativeDriver: true},
267+
)}
268+
/>
262269
</View>
263270
);
264271
}

0 commit comments

Comments
 (0)