mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-23 20:01:01 +08:00
Native Animated - Support multiple events attached to the same prop
Summary: Fixes a bug that happens when trying to use ScrollView with sticky headers and native `Animated.event` with `onScroll`. Made a few changes to the ListViewPaging UIExplorer example to repro https://gist.github.com/janicduplessis/17e2fcd99c6ea49ced2954d881011b09. What happens is we need to be able to add multiple events to the same prop + viewTag pair. To do that I simple changed the data structure to `Map<prop+viewTag, List<AnimatedEventDriver>>` and try to optimize for the case where there is only one item in the list since it will be the case 99% of the time. **Test plan** Tested by reproducing the bug with the above gist and made sure it was fixed after applying this diff. Closes https://github.com/facebook/react-native/pull/12697 Differential Revision: D4656347 Pulled By: sahrens fbshipit-source-id: b5c36ba796f478e56028c7a95bc0f86bc54cb2ce
This commit is contained in:
committed by
Facebook Github Bot
parent
59257d6976
commit
c708234f66
@@ -33,7 +33,9 @@
|
||||
{
|
||||
RCTUIManager *_uiManager;
|
||||
NSMutableDictionary<NSNumber *, RCTAnimatedNode *> *_animationNodes;
|
||||
NSMutableDictionary<NSString *, RCTEventAnimation *> *_eventDrivers;
|
||||
// Mapping of a view tag and an event name to a list of event animation drivers. 99% of the time
|
||||
// there will be only one driver per mapping so all code code should be optimized around that.
|
||||
NSMutableDictionary<NSString *, NSMutableArray<RCTEventAnimation *> *> *_eventDrivers;
|
||||
NSMutableSet<id<RCTAnimationDriver>> *_activeAnimations;
|
||||
CADisplayLink *_displayLink;
|
||||
}
|
||||
@@ -264,15 +266,36 @@
|
||||
NSArray<NSString *> *eventPath = [RCTConvert NSStringArray:eventMapping[@"nativeEventPath"]];
|
||||
|
||||
RCTEventAnimation *driver =
|
||||
[[RCTEventAnimation alloc] initWithEventPath:eventPath valueNode:(RCTValueAnimatedNode *)node];
|
||||
[[RCTEventAnimation alloc] initWithEventPath:eventPath valueNode:(RCTValueAnimatedNode *)node];
|
||||
|
||||
_eventDrivers[[NSString stringWithFormat:@"%@%@", viewTag, eventName]] = driver;
|
||||
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, eventName];
|
||||
if (_eventDrivers[key] != nil) {
|
||||
[_eventDrivers[key] addObject:driver];
|
||||
} else {
|
||||
NSMutableArray<RCTEventAnimation *> *drivers = [NSMutableArray new];
|
||||
[drivers addObject:driver];
|
||||
_eventDrivers[key] = drivers;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAnimatedEventFromView:(nonnull NSNumber *)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
animatedNodeTag:(nonnull NSNumber *)animatedNodeTag
|
||||
{
|
||||
[_eventDrivers removeObjectForKey:[NSString stringWithFormat:@"%@%@", viewTag, eventName]];
|
||||
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, eventName];
|
||||
if (_eventDrivers[key] != nil) {
|
||||
if (_eventDrivers[key].count == 1) {
|
||||
[_eventDrivers removeObjectForKey:key];
|
||||
} else {
|
||||
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
|
||||
for (NSUInteger i = 0; i < driversForKey.count; i++) {
|
||||
if (driversForKey[i].valueNode.nodeTag == animatedNodeTag) {
|
||||
[driversForKey removeObjectAtIndex:i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleAnimatedEvent:(id<RCTEvent>)event
|
||||
@@ -282,9 +305,12 @@
|
||||
}
|
||||
|
||||
NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, event.eventName];
|
||||
RCTEventAnimation *driver = _eventDrivers[key];
|
||||
if (driver) {
|
||||
[driver updateWithEvent:event];
|
||||
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
|
||||
if (driversForKey) {
|
||||
for (RCTEventAnimation *driver in driversForKey) {
|
||||
[driver updateWithEvent:event];
|
||||
}
|
||||
|
||||
[self updateAnimations];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user