Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Add possibility to disable buttons in action sheet ios #28792

Closed
wants to merge 9 commits into from
2 changes: 2 additions & 0 deletions Libraries/ActionSheetIOS/ActionSheetIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -49,6 +50,7 @@ const ActionSheetIOS = {
+anchor?: ?number,
+tintColor?: ColorValue | ProcessedColorValue,
+userInterfaceStyle?: string,
+disabledButtonIndices?: Array<number>,
|},
callback: (buttonIndex: number) => void,
) {
Expand Down
1 change: 1 addition & 0 deletions Libraries/ActionSheetIOS/NativeActionSheetManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Spec extends TurboModule {
+anchor?: ?number,
+tintColor?: ?number,
+userInterfaceStyle?: ?string,
+disabledButtonIndices?: Array<number>,
|},
callback: (buttonIndex: number) => void,
) => void;
Expand Down
32 changes: 32 additions & 0 deletions RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -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|};
Expand Down Expand Up @@ -138,6 +139,37 @@ class ActionSheetAnchorExample extends React.Component<
};
}

class ActionSheetDisabledExample extends React.Component<Props, State> {
state = {
clicked: 'none',
};

render() {
return (
<View>
<Text onPress={this.showActionSheet} style={style.button}>
Click to show the ActionSheet
</Text>
<Text>Clicked button: {this.state.clicked}</Text>
</View>
);
}

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,
Expand Down
6 changes: 6 additions & 0 deletions React/CoreModules/RCTActionSheetManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ - (void)presentViewController:(UIViewController *)alertController
NSInteger cancelButtonIndex =
options.cancelButtonIndex() ? [RCTConvert NSInteger:@(*options.cancelButtonIndex())] : -1;
NSArray<NSNumber *> *destructiveButtonIndices;
NSArray<NSNumber *> *disabledButtonIndices = [RCTConvert NSArray:options[@"disabledButtonIndices"]];
if (options.destructiveButtonIndices()) {
destructiveButtonIndices = RCTConvertVecToArray(*options.destructiveButtonIndices(), ^id(double element) {
return @(element);
Expand All @@ -98,6 +99,7 @@ - (void)presentViewController:(UIViewController *)alertController
@"destructiveButtonIndices" : destructiveButtonIndices,
@"anchor" : anchor,
@"tintColor" : tintColor,
@"destructiveButtonIndices" : destructiveButtonIndices,
lukewalczak marked this conversation as resolved.
Show resolved Hide resolved
});
return;
}
Expand Down Expand Up @@ -128,6 +130,10 @@ - (void)presentViewController:(UIViewController *)alertController
handler:^(__unused UIAlertAction *action) {
callback(@[ @(localIndex) ]);
}]];

if ([disabledButtonIndices containsObject:@(localIndex)]) {
Copy link
Contributor

@vonovak vonovak May 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a biggie, but instead of asking if the action is disabled for each of the actions, you can iterate over indices in disabledButtonIndices and call setEnabled:false for each index you know is disabled. I just find it a little more elegant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Thanks for suggestion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that I'm looking at it, the problem you didn't have before but have now is handling the situation when disabledButtonIndices contains index that is out of bounds.

Copy link
Contributor Author

@lukewalczak lukewalczak May 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed! Disable button if its index is within the allowable range, otherwise throw an error with a message.

[alertController.actions[localIndex] setEnabled:false];
}

index++;
}
Expand Down