From 1643ea504f9515fde200dd1597f139aabc3a7626 Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Fri, 24 Feb 2023 14:10:28 +0100 Subject: [PATCH] Make all events on iOS flush updates immediately (#4097) ## Summary Before this change we'd only call `performOperations` for a subset of filtered events (initially introduced in #312). The event's that weren't considered "direct" would require additional animation frame for having their updates flushed. This change makes it so that we call `performOperations` for all types of events therefore matching the behavior [on Android](https://github.com/software-mansion/react-native-reanimated/blob/99b8b3ed56e36ca615cce7164ccaf04d154571b1/android/src/main/java/com/swmansion/reanimated/NodesManager.java#L283) A consequence of this change was that for some event types, the updates reanimated was performing weren't getting flushed onto screen. Namely, we noticed this problem in Pager example where a view pager component with some custom set of events is used and event handlers update shared values. Even though such event would trigger shared value update, and these updates would trigger the style to recalculate and we'd even call updateProps method to apply the updated props, we'd still see no result as in that example the changes require layout run. Without `performOperation` call the layout would not be executed unless react would rerender or other time-based animation would run. The problem became apparent after #3970 where we changed the place where updates are performed from requestAnimationFrame to setImmediate. Before this change, since we were running the updates in "animation frame" the `performOperation` method was being run by the frame scheduler. We, however were getting these updates delayed by one frame because of that. This issue also wasn't noticed prior to shareable rewrite from #3722 because before, we were always starting frame updater for every single update happening to shared value even if it was due to an event. As a result, we were getting the stuff updated on screen but again, with a delay of one frame. ## Test plan Run pager example on iOS. --- ios/REANodesManager.mm | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/ios/REANodesManager.mm b/ios/REANodesManager.mm index 7bc9e78de74..da95472d254 100644 --- a/ios/REANodesManager.mm +++ b/ios/REANodesManager.mm @@ -313,24 +313,6 @@ - (void)enqueueUpdateViewOnNativeThread:(nonnull NSNumber *)reactTag } #endif -- (BOOL)isDirectEvent:(id)event -{ - static NSArray *directEventNames; - static dispatch_once_t directEventNamesToken; - dispatch_once(&directEventNamesToken, ^{ - directEventNames = @[ - @"topContentSizeChange", - @"topMomentumScrollBegin", - @"topMomentumScrollEnd", - @"topScroll", - @"topScrollBeginDrag", - @"topScrollEndDrag" - ]; - }); - - return [directEventNames containsObject:RCTNormalizeInputEventName(event.eventName)]; -} - - (void)dispatchEvent:(id)event { NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, RCTNormalizeInputEventName(event.eventName)]; @@ -349,9 +331,7 @@ - (void)dispatchEvent:(id)event return; } eventHandler(eventHash, event); - if ([strongSelf isDirectEvent:event]) { - [strongSelf performOperations]; - } + [strongSelf performOperations]; }); } }