Skip to content

Commit

Permalink
Make all events on iOS flush updates immediately (software-mansion#4097)
Browse files Browse the repository at this point in the history
## Summary

Before this change we'd only call `performOperations` for a subset of
filtered events (initially introduced in software-mansion#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 software-mansion#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 software-mansion#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.
  • Loading branch information
kmagiera authored and fluiddot committed Jun 5, 2023
1 parent 269b4f0 commit 1643ea5
Showing 1 changed file with 1 addition and 21 deletions.
22 changes: 1 addition & 21 deletions ios/REANodesManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -313,24 +313,6 @@ - (void)enqueueUpdateViewOnNativeThread:(nonnull NSNumber *)reactTag
}
#endif

- (BOOL)isDirectEvent:(id<RCTEvent>)event
{
static NSArray<NSString *> *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<RCTEvent>)event
{
NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, RCTNormalizeInputEventName(event.eventName)];
Expand All @@ -349,9 +331,7 @@ - (void)dispatchEvent:(id<RCTEvent>)event
return;
}
eventHandler(eventHash, event);
if ([strongSelf isDirectEvent:event]) {
[strongSelf performOperations];
}
[strongSelf performOperations];
});
}
}
Expand Down

0 comments on commit 1643ea5

Please sign in to comment.