Skip to content

Commit f1506be

Browse files
authored
fix(action-sheet): correct some cancelable misbehaviors (#2491)
1 parent 9d20478 commit f1506be

File tree

5 files changed

+36
-38
lines changed

5 files changed

+36
-38
lines changed

action-sheet/README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,20 @@ to select.
8484

8585
#### ShowActionsResult
8686

87-
| Prop | Type | Description | Since |
88-
| -------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
89-
| **`index`** | <code>number</code> | The index of the clicked option (Zero-based), or -1 if the sheet was canceled. On iOS, if there is a button with <a href="#actionsheetbuttonstyle">ActionSheetButtonStyle.Cancel</a>, and user clicks outside the sheet, the index of the cancel option is returned | 1.0.0 |
90-
| **`canceled`** | <code>boolean</code> | True if sheet was canceled by user; False otherwise On Web, requires having @ionic/pwa-elements version 3.4.0 or higher. | 8.1.0 |
87+
| Prop | Type | Description | Since |
88+
| -------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
89+
| **`index`** | <code>number</code> | The index of the clicked option (Zero-based), or -1 if the Action Sheet was canceled. On iOS, if there is a button with <a href="#actionsheetbuttonstyle">ActionSheetButtonStyle.Cancel</a>, and user clicks outside the Action Sheet, the index of the Cancel button is returned. | 1.0.0 |
90+
| **`canceled`** | <code>boolean</code> | True if the Action Sheet was canceled by user; False otherwise. On Web, requires having @ionic/pwa-elements version 3.4.0 or higher. | 8.1.0 |
9191

9292

9393
#### ShowActionsOptions
9494

95-
| Prop | Type | Description | Since |
96-
| ---------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
97-
| **`title`** | <code>string</code> | The title of the Action Sheet. | 1.0.0 |
98-
| **`message`** | <code>string</code> | A message to show under the title. This option is only supported on iOS. | 1.0.0 |
99-
| **`options`** | <code>ActionSheetButton[]</code> | Options the user can choose from. | 1.0.0 |
100-
| **`cancelable`** | <code>boolean</code> | If true, sheet is canceled when clicked outside; If false, it is not. By default, false. Not available on iOS, sheet is always cancelable by clicking outside of it. On Web, requires having @ionic/pwa-elements version 3.4.0 or higher. | 8.1.0 |
95+
| Prop | Type | Description | Default | Since |
96+
| ---------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
97+
| **`title`** | <code>string</code> | The title of the Action Sheet. | | 1.0.0 |
98+
| **`message`** | <code>string</code> | A message to show under the title. This option is only supported on iOS. | | 1.0.0 |
99+
| **`options`** | <code>ActionSheetButton[]</code> | Options the user can choose from. | | 1.0.0 |
100+
| **`cancelable`** | <code>boolean</code> | If true, the Action Sheet is canceled when clicked outside; If false, it is not. On iOS, it's not available if there is a button with <a href="#actionsheetbuttonstyle">ActionSheetButtonStyle.Cancel</a>, or on iOS 26+. In those cases, the Action Sheet is always cancelable by clicking outside of it. On Web, requires having @ionic/pwa-elements version 3.4.0 or higher. | <code>false</code> | 8.1.0 |
101101

102102

103103
#### ActionSheetButton
@@ -114,10 +114,10 @@ to select.
114114

115115
#### ActionSheetButtonStyle
116116

117-
| Members | Value | Description | Since |
118-
| ----------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- | ----- |
119-
| **`Default`** | <code>'DEFAULT'</code> | Default style of the option. | 1.0.0 |
120-
| **`Destructive`** | <code>'DESTRUCTIVE'</code> | Style to use on destructive options. | 1.0.0 |
121-
| **`Cancel`** | <code>'CANCEL'</code> | Style to use on the option that cancels the Action Sheet. If used, should be on the latest availabe option. | 1.0.0 |
117+
| Members | Value | Description | Since |
118+
| ----------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
119+
| **`Default`** | <code>'DEFAULT'</code> | Default style of the option. | 1.0.0 |
120+
| **`Destructive`** | <code>'DESTRUCTIVE'</code> | Style to use on destructive options. | 1.0.0 |
121+
| **`Cancel`** | <code>'CANCEL'</code> | Style to use on the option that cancels the Action Sheet. If used, should be on the latest available option. On iOS 26+ is not displayed, the Action Sheet is cancelable by tapping outside. | 1.0.0 |
122122

123123
</docgen-api>

action-sheet/android/src/main/java/com/capacitorjs/plugins/actionsheet/ActionSheetPlugin.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ public void showActions(final PluginCall call) {
4545
implementation.setOnCancelListener(() -> resolve(call, -1));
4646
}
4747
implementation.setOnSelectedListener((index) -> {
48-
JSObject ret = new JSObject();
49-
ret.put("index", index);
50-
call.resolve(ret);
48+
resolve(call, index);
5149
implementation.dismiss();
5250
});
5351
implementation.show(getActivity().getSupportFragmentManager(), "capacitorModalsActionSheet");

action-sheet/ios/Sources/ActionSheetPlugin/ActionSheetPlugin.swift

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,10 @@ public class ActionSheetPlugin: CAPPlugin, CAPBridgedPlugin, UIAdaptivePresentat
3333
buttonStyle = .cancel
3434
}
3535
let action = UIAlertAction(title: title, style: buttonStyle, handler: { [weak self] (_) in
36-
if buttonStyle == .cancel {
37-
call.actionSheetCanceled()
38-
} else {
39-
call.resolve([
40-
"index": index,
41-
"canceled": false
42-
])
43-
}
36+
call.resolve([
37+
"index": index,
38+
"canceled": buttonStyle == .cancel
39+
])
4440
self?.currentCall = nil
4541
})
4642
alertActions.append(action)
@@ -51,27 +47,28 @@ public class ActionSheetPlugin: CAPPlugin, CAPBridgedPlugin, UIAdaptivePresentat
5147
self?.setCenteredPopover(alertController)
5248
self?.bridge?.viewController?.present(alertController, animated: true) {
5349
if !hasCancellableButton {
54-
self?.setupCancelationListerners(alertController, call)
50+
self?.setupCancelationListeners(alertController, call)
5551
}
5652
}
5753
}
5854
}
5955
}
6056

61-
private func setupCancelationListerners(_ alertController: UIAlertController, _ call: CAPPluginCall) {
57+
private func setupCancelationListeners(_ alertController: UIAlertController, _ call: CAPPluginCall) {
58+
let cancelable = call.getBool("cancelable", false)
6259
if #available(iOS 26, *) {
6360
self.currentCall = call
6461
alertController.presentationController?.delegate = self
65-
} else {
62+
} else if cancelable {
6663
// For iOS versions below 26, setting the presentation controller delegate would result in a crash
6764
// "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The presentation controller of an alert controller presenting as an alert must not have its delegate modified"
6865
// Hence, the alternative by adding a gesture recognizer (which only works for iOS versions below 26)
6966
let gestureRecognizer = TapGestureRecognizerWithClosure {
7067
alertController.dismiss(animated: true, completion: nil)
7168
call.actionSheetCanceled()
7269
}
73-
let backroundView = alertController.view.superview?.subviews[0]
74-
backroundView?.addGestureRecognizer(gestureRecognizer)
70+
let backgroundView = alertController.view.superview?.subviews[0]
71+
backgroundView?.addGestureRecognizer(gestureRecognizer)
7572
}
7673
}
7774

action-sheet/src/definitions.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ export interface ShowActionsOptions {
2323
options: ActionSheetButton[];
2424

2525
/**
26-
* If true, sheet is canceled when clicked outside; If false, it is not. By default, false.
26+
* If true, the Action Sheet is canceled when clicked outside; If false, it is not.
2727
*
28-
* Not available on iOS, sheet is always cancelable by clicking outside of it.
28+
* On iOS, it's not available if there is a button with ActionSheetButtonStyle.Cancel, or on iOS 26+.
29+
* In those cases, the Action Sheet is always cancelable by clicking outside of it.
2930
*
3031
* On Web, requires having @ionic/pwa-elements version 3.4.0 or higher.
3132
*
33+
* @default false
3234
* @since 8.1.0
3335
*/
3436
cancelable?: boolean;
@@ -51,7 +53,8 @@ export enum ActionSheetButtonStyle {
5153

5254
/**
5355
* Style to use on the option that cancels the Action Sheet.
54-
* If used, should be on the latest availabe option.
56+
* If used, should be on the latest available option.
57+
* On iOS 26+ is not displayed, the Action Sheet is cancelable by tapping outside.
5558
*
5659
* @since 1.0.0
5760
*/
@@ -87,15 +90,15 @@ export interface ActionSheetButton {
8790

8891
export interface ShowActionsResult {
8992
/**
90-
* The index of the clicked option (Zero-based), or -1 if the sheet was canceled.
93+
* The index of the clicked option (Zero-based), or -1 if the Action Sheet was canceled.
9194
*
92-
* On iOS, if there is a button with ActionSheetButtonStyle.Cancel, and user clicks outside the sheet, the index of the cancel option is returned
95+
* On iOS, if there is a button with ActionSheetButtonStyle.Cancel, and user clicks outside the Action Sheet, the index of the Cancel button is returned.
9396
*
9497
* @since 1.0.0
9598
*/
9699
index: number;
97100
/**
98-
* True if sheet was canceled by user; False otherwise
101+
* True if the Action Sheet was canceled by user; False otherwise.
99102
*
100103
* On Web, requires having @ionic/pwa-elements version 3.4.0 or higher.
101104
*

action-sheet/src/web.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class ActionSheetWeb extends WebPlugin implements ActionSheetPlugin {
1111
document.body.appendChild(actionSheet);
1212
}
1313
actionSheet.header = options.title;
14-
actionSheet.cancelable = options.cancelable;
14+
actionSheet.cancelable = options.cancelable ?? false;
1515
actionSheet.options = options.options;
1616
actionSheet.addEventListener('onSelection', async (e: any) => {
1717
const selection = e.detail;

0 commit comments

Comments
 (0)