From 19d7949978d73219660ae8e201655034606002fb Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Thu, 30 Apr 2020 15:42:17 +0200 Subject: [PATCH 1/8] Add possibility to disable buttons in action sheet ios --- .../ActionSheetIOS/RCTActionSheetManager.m | 5 +++ RNTester/js/ActionSheetIOSExample.js | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/Libraries/ActionSheetIOS/RCTActionSheetManager.m b/Libraries/ActionSheetIOS/RCTActionSheetManager.m index 9eca118126ca16..0b06d10071e5f7 100644 --- a/Libraries/ActionSheetIOS/RCTActionSheetManager.m +++ b/Libraries/ActionSheetIOS/RCTActionSheetManager.m @@ -66,6 +66,7 @@ - (void)presentViewController:(UIViewController *)alertController NSArray *buttons = [RCTConvert NSStringArray:options[@"options"]]; NSInteger cancelButtonIndex = options[@"cancelButtonIndex"] ? [RCTConvert NSInteger:options[@"cancelButtonIndex"]] : -1; NSArray *destructiveButtonIndices; + NSArray *disabledButtonIndices = [RCTConvert NSArray:options[@"disabledButtonIndices"]]; if ([options[@"destructiveButtonIndex"] isKindOfClass:[NSArray class]]) { destructiveButtonIndices = [RCTConvert NSArray:options[@"destructiveButtonIndex"]]; } else { @@ -108,6 +109,10 @@ - (void)presentViewController:(UIViewController *)alertController callback(@[@(localIndex)]); }]]; + if ([disabledButtonIndices containsObject:@(localIndex)]) { + [alertController.actions[localIndex] setEnabled:false]; + } + index++; } diff --git a/RNTester/js/ActionSheetIOSExample.js b/RNTester/js/ActionSheetIOSExample.js index 1f7abc2e79713f..2e6ade55410cea 100644 --- a/RNTester/js/ActionSheetIOSExample.js +++ b/RNTester/js/ActionSheetIOSExample.js @@ -25,6 +25,7 @@ const ScreenshotManager = NativeModules.ScreenshotManager; const BUTTONS = ['Option 0', 'Option 1', 'Option 2', 'Delete', 'Cancel']; const DESTRUCTIVE_INDEX = 3; const CANCEL_INDEX = 4; +const DISABLED_BUTTON_INDICES = [1, 2]; type Props = $ReadOnly<{||}>; type State = {|clicked: string|}; @@ -138,6 +139,37 @@ class ActionSheetAnchorExample extends React.Component< }; } +class ActionSheetDisabledExample extends React.Component { + state = { + clicked: 'none', + }; + + render() { + return ( + + + Click to show the ActionSheet + + Clicked button: {this.state.clicked} + + ); + } + + showActionSheet = () => { + ActionSheetIOS.showActionSheetWithOptions( + { + options: BUTTONS, + cancelButtonIndex: CANCEL_INDEX, + destructiveButtonIndex: DESTRUCTIVE_INDEX, + disabledButtonIndices: DISABLED_BUTTON_INDICES, + }, + buttonIndex => { + this.setState({clicked: BUTTONS[buttonIndex]}); + }, + ); + }; +} + class ShareActionSheetExample extends React.Component< $FlowFixMeProps, $FlowFixMeState, @@ -315,6 +347,12 @@ exports.examples = [ return ; }, }, + { + title: 'Show Action Sheet with disabled buttons', + render(): React.Element { + return ; + }, + }, { title: 'Show Share Action Sheet', render(): React.Element { From c9b4b0e3080255496c30225fd952525c1995f5f7 Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Thu, 30 Apr 2020 19:18:43 +0200 Subject: [PATCH 2/8] Fix flow in ActionSheetIOS after adding new property --- Libraries/ActionSheetIOS/ActionSheetIOS.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Libraries/ActionSheetIOS/ActionSheetIOS.js b/Libraries/ActionSheetIOS/ActionSheetIOS.js index 129de677d8b17d..6c0a5be6d2901c 100644 --- a/Libraries/ActionSheetIOS/ActionSheetIOS.js +++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js @@ -30,6 +30,7 @@ const ActionSheetIOS = { * - `destructiveButtonIndex` (int or array of ints) - index or indices of destructive buttons in `options` * - `title` (string) - a title to show above the action sheet * - `message` (string) - a message to show below the title + * - `disabledButtonIndices` (array of numbers) - a list of button indices which should be disabled * * The 'callback' function takes one parameter, the zero-based index * of the selected item. @@ -45,6 +46,7 @@ const ActionSheetIOS = { +cancelButtonIndex?: ?number, +anchor?: ?number, +tintColor?: number | string, + +disabledButtonIndices?: Array, |}, callback: (buttonIndex: number) => void, ) { From c004e37b66c9f9ae8ed9d52c9bae37a3b48f88f0 Mon Sep 17 00:00:00 2001 From: Luke Walczak Date: Thu, 30 Apr 2020 20:58:20 +0200 Subject: [PATCH 3/8] Update React/CoreModules/RCTActionSheetManager.mm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: MichaƂ Osadnik --- React/CoreModules/RCTActionSheetManager.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index a9daec0f032cbd..dfcf062403641a 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -99,7 +99,7 @@ - (void)presentViewController:(UIViewController *)alertController @"destructiveButtonIndices" : destructiveButtonIndices, @"anchor" : anchor, @"tintColor" : tintColor, - @"destructiveButtonIndices" : destructiveButtonIndices, + @"disabledButtonIndices" : disabledButtonIndices, }); return; } From e632c3d2446d3c62deb754c25a97319b78b27146 Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Fri, 1 May 2020 13:02:06 +0200 Subject: [PATCH 4/8] Use new example, convert new option --- .../FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h | 6 ++++++ .../js/examples/ActionSheetIOS/ActionSheetIOSExample.js | 6 ++++++ React/CoreModules/RCTActionSheetManager.mm | 5 +++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index 4323cd25040c21..56a2c6b9c16371 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -114,6 +114,7 @@ namespace JS { NSString *message() const; folly::Optional> options() const; folly::Optional> destructiveButtonIndices() const; + folly::Optional> disabledButtonIndices() const; folly::Optional cancelButtonIndex() const; folly::Optional anchor() const; folly::Optional tintColor() const; @@ -2922,6 +2923,11 @@ inline folly::Optional> JS::NativeActionShee id const p = _v[@"destructiveButtonIndices"]; return RCTBridgingToOptionalVec(p, ^double(id itemValue_0) { return RCTBridgingToDouble(itemValue_0); }); } +inline folly::Optional> JS::NativeActionSheetManager::SpecShowActionSheetWithOptionsOptions::disabledButtonIndices() const +{ + id const p = _v[@"disabledButtonIndices"]; + return RCTBridgingToOptionalVec(p, ^double(id itemValue_0) { return RCTBridgingToDouble(itemValue_0); }); +} inline folly::Optional JS::NativeActionSheetManager::SpecShowActionSheetWithOptionsOptions::cancelButtonIndex() const { id const p = _v[@"cancelButtonIndex"]; diff --git a/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js b/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js index f16ac41e0e9fa0..a5ea2d79771d82 100644 --- a/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js +++ b/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js @@ -347,6 +347,12 @@ exports.examples = [ return ; }, }, + { + title: 'Show Action Sheet with disabled buttons', + render(): React.Element { + return ; + }, + }, { title: 'Show Share Action Sheet', render(): React.Element { diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index dfcf062403641a..1fb3af060ab676 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -76,7 +76,9 @@ - (void)presentViewController:(UIViewController *)alertController NSInteger cancelButtonIndex = options.cancelButtonIndex() ? [RCTConvert NSInteger:@(*options.cancelButtonIndex())] : -1; NSArray *destructiveButtonIndices; - NSArray *disabledButtonIndices = [RCTConvert NSArray:options[@"disabledButtonIndices"]]; + NSArray *disabledButtonIndices = RCTConvertVecToArray(*options.disabledButtonIndices(), ^id(double element) { + return @(element); + }); if (options.destructiveButtonIndices()) { destructiveButtonIndices = RCTConvertVecToArray(*options.destructiveButtonIndices(), ^id(double element) { return @(element); @@ -130,7 +132,6 @@ - (void)presentViewController:(UIViewController *)alertController handler:^(__unused UIAlertAction *action) { callback(@[ @(localIndex) ]); }]]; - if ([disabledButtonIndices containsObject:@(localIndex)]) { [alertController.actions[localIndex] setEnabled:false]; } From 5d020eea8953c9aeb1f95fccef4bd124d39f1c5e Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Mon, 4 May 2020 12:04:49 +0200 Subject: [PATCH 5/8] Iterate over indices to disable actions --- React/CoreModules/RCTActionSheetManager.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index 1fb3af060ab676..c773f2fd25ade7 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -132,13 +132,14 @@ - (void)presentViewController:(UIViewController *)alertController handler:^(__unused UIAlertAction *action) { callback(@[ @(localIndex) ]); }]]; - if ([disabledButtonIndices containsObject:@(localIndex)]) { - [alertController.actions[localIndex] setEnabled:false]; - } index++; } + for (NSNumber *disabledButtonIndex in disabledButtonIndices) { + [alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false]; + } + alertController.view.tintColor = tintColor; #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 From 0b9350a9c1a3807ac7225e94ec388c346f704244 Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Mon, 4 May 2020 16:18:37 +0200 Subject: [PATCH 6/8] Handle case when index is out of bounds --- React/CoreModules/RCTActionSheetManager.mm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index c773f2fd25ade7..538603899ea3c4 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -137,7 +137,12 @@ - (void)presentViewController:(UIViewController *)alertController } for (NSNumber *disabledButtonIndex in disabledButtonIndices) { - [alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false]; + if ([disabledButtonIndex integerValue] < buttons.count) { + [alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false]; + } else { + RCTLogError(@"Index %li is out of bounds. Maximum index value is %lu.", (long)[disabledButtonIndex integerValue], buttons.count - 1); + return; + } } alertController.view.tintColor = tintColor; From da3a6752c26267eb65718da247132f5df330fb29 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 4 May 2020 19:57:31 -0700 Subject: [PATCH 7/8] Update RCTActionSheetManager.mm --- React/CoreModules/RCTActionSheetManager.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index 538603899ea3c4..8c93bc55b326f1 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -140,11 +140,11 @@ - (void)presentViewController:(UIViewController *)alertController if ([disabledButtonIndex integerValue] < buttons.count) { [alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false]; } else { - RCTLogError(@"Index %li is out of bounds. Maximum index value is %lu.", (long)[disabledButtonIndex integerValue], buttons.count - 1); - return; + RCTLogError(@"Index %li from `disabledButtonIndices` is out of bounds. Maximum index value is %lu.", (long)[disabledButtonIndex integerValue], buttons.count - 1); + return; } } - + alertController.view.tintColor = tintColor; #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 From 75003a3742351229f4c304bc0a51fcbd9a7e8543 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 5 May 2020 18:15:14 -0700 Subject: [PATCH 8/8] Update RCTActionSheetManager.mm --- React/CoreModules/RCTActionSheetManager.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index 8c93bc55b326f1..62e38b29e1b13b 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -140,7 +140,7 @@ - (void)presentViewController:(UIViewController *)alertController if ([disabledButtonIndex integerValue] < buttons.count) { [alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false]; } else { - RCTLogError(@"Index %li from `disabledButtonIndices` is out of bounds. Maximum index value is %lu.", (long)[disabledButtonIndex integerValue], buttons.count - 1); + RCTLogError(@"Index %@ from `disabledButtonIndices` is out of bounds. Maximum index value is %@.", @([disabledButtonIndex integerValue]), @(buttons.count - 1)); return; } }