From d26c76ca47a7ef35e2ab3fc0cc7440fc8bf62f38 Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Tue, 26 May 2020 13:45:58 +0200 Subject: [PATCH 1/2] Add possibility to disable buttons in action sheet ios --- Libraries/ActionSheetIOS/ActionSheetIOS.js | 2 + .../NativeActionSheetManager.js | 1 + .../FBReactNativeSpec/FBReactNativeSpec.h | 6 +++ .../ActionSheetIOS/ActionSheetIOSExample.js | 38 +++++++++++++++++++ React/CoreModules/RCTActionSheetManager.mm | 18 +++++++++ 5 files changed, 65 insertions(+) diff --git a/Libraries/ActionSheetIOS/ActionSheetIOS.js b/Libraries/ActionSheetIOS/ActionSheetIOS.js index 076ab004a56eb3..9852791cdf67a7 100644 --- a/Libraries/ActionSheetIOS/ActionSheetIOS.js +++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js @@ -33,6 +33,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. @@ -49,6 +50,7 @@ const ActionSheetIOS = { +anchor?: ?number, +tintColor?: ColorValue | ProcessedColorValue, +userInterfaceStyle?: string, + +disabledButtonIndices?: Array, |}, callback: (buttonIndex: number) => void, ) { diff --git a/Libraries/ActionSheetIOS/NativeActionSheetManager.js b/Libraries/ActionSheetIOS/NativeActionSheetManager.js index 063d9147e1d69b..6d86200d9accd6 100644 --- a/Libraries/ActionSheetIOS/NativeActionSheetManager.js +++ b/Libraries/ActionSheetIOS/NativeActionSheetManager.js @@ -25,6 +25,7 @@ export interface Spec extends TurboModule { +anchor?: ?number, +tintColor?: ?number, +userInterfaceStyle?: ?string, + +disabledButtonIndices?: Array, |}, callback: (buttonIndex: number) => void, ) => void; diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index 8cd831f027231c..b87c4859da1459 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; @@ -2921,6 +2922,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 c1130357829df5..19a82fdef1c8b1 100644 --- a/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js +++ b/RNTester/js/examples/ActionSheetIOS/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.0, 2.0]; 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 { diff --git a/React/CoreModules/RCTActionSheetManager.mm b/React/CoreModules/RCTActionSheetManager.mm index 754e461157349d..c2eae7c9fe8808 100644 --- a/React/CoreModules/RCTActionSheetManager.mm +++ b/React/CoreModules/RCTActionSheetManager.mm @@ -73,9 +73,15 @@ - (void)presentViewController:(UIViewController *)alertController NSArray *buttons = RCTConvertOptionalVecToArray(options.options(), ^id(NSString *element) { return element; }); + NSArray *disabledButtonIndices; NSInteger cancelButtonIndex = options.cancelButtonIndex() ? [RCTConvert NSInteger:@(*options.cancelButtonIndex())] : -1; NSArray *destructiveButtonIndices; + if (options.disabledButtonIndices()) { + disabledButtonIndices = RCTConvertVecToArray(*options.disabledButtonIndices(), ^id(double element) { + return @(element); + }); + } if (options.destructiveButtonIndices()) { destructiveButtonIndices = RCTConvertVecToArray(*options.destructiveButtonIndices(), ^id(double element) { return @(element); @@ -98,6 +104,7 @@ - (void)presentViewController:(UIViewController *)alertController @"destructiveButtonIndices" : destructiveButtonIndices, @"anchor" : anchor, @"tintColor" : tintColor, + @"disabledButtonIndices" : disabledButtonIndices, }); return; } @@ -132,6 +139,17 @@ - (void)presentViewController:(UIViewController *)alertController index++; } + if (disabledButtonIndices) { + for (NSNumber *disabledButtonIndex in disabledButtonIndices) { + if ([disabledButtonIndex integerValue] < buttons.count) { + [alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false]; + } else { + RCTLogError(@"Index %@ from `disabledButtonIndices` is out of bounds. Maximum index value is %@.", @([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 7d82791c6877dc1e3bb3da8bf5ceee1bd720a5b8 Mon Sep 17 00:00:00 2001 From: Luke Walczak Date: Fri, 29 May 2020 16:20:16 +0200 Subject: [PATCH 2/2] Update ActionSheetIOSExample.js --- RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js b/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js index 19a82fdef1c8b1..a5ea2d79771d82 100644 --- a/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js +++ b/RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js @@ -25,7 +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.0, 2.0]; +const DISABLED_BUTTON_INDICES = [1, 2]; type Props = $ReadOnly<{||}>; type State = {|clicked: string|};