Skip to content

Commit

Permalink
Fix action sheet callback invoked more than once on iPad (#33099)
Browse files Browse the repository at this point in the history
Summary:
iOS will sometimes invoke the UIAlertAction handler for the cancel button more than once on iPad. This can be reproduced relatively easily by having a button that opens an action sheet and spam tapping outside the action sheet while it is opening. Since native module callbacks can only be invoked once this causes the app to crash here https://github.com/facebook/react-native/blob/main/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm#L206.

## Changelog

[iOS] [Fixed] - Fix action sheet callback invoked more than once on iPad

Pull Request resolved: #33099

Test Plan: Tested on iPad simulator to reproduce the crash and verified that this fixes it.

Reviewed By: philIip

Differential Revision: D34215327

Pulled By: ShikaSD

fbshipit-source-id: 6f406e4df737a57e6dd702dd54260aa72eab31d6
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Feb 16, 2022
1 parent c1a55c7 commit 8935d6e
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion React/CoreModules/RCTActionSheetManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ - (void)presentViewController:(UIViewController *)alertController

NSInteger index = 0;
bool isCancelButtonIndex = false;
// The handler for a button might get called more than once when tapping outside
// the action sheet on iPad. RCTResponseSenderBlock can only be called once so
// keep track of callback invocation here.
__block bool callbackInvoked = false;
for (NSString *option in buttons) {
UIAlertActionStyle style = UIAlertActionStyleDefault;
if ([destructiveButtonIndices containsObject:@(index)]) {
Expand All @@ -131,7 +135,10 @@ - (void)presentViewController:(UIViewController *)alertController
UIAlertAction *actionButton = [UIAlertAction actionWithTitle:option
style:style
handler:^(__unused UIAlertAction *action) {
callback(@[ @(localIndex) ]);
if (!callbackInvoked) {
callbackInvoked = true;
callback(@[ @(localIndex) ]);
}
}];
if (isCancelButtonIndex) {
[actionButton setValue:cancelButtonTintColor forKey:@"titleTextColor"];
Expand Down

0 comments on commit 8935d6e

Please sign in to comment.