diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index cd5f7e8c1f..d0a3c3fe71 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -1,4 +1,4 @@ -import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, h, writeTask } from '@stencil/core'; +import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, h, writeTask } from '@stencil/core'; import { config } from '../../global/config'; import { getIonMode } from '../../global/ionic-global'; @@ -121,6 +121,15 @@ export class Modal implements ComponentInterface, OverlayInterface { */ @Event({ eventName: 'ionModalDidDismiss' }) didDismiss!: EventEmitter; + @Watch('swipeToClose') + swipeToCloseChanged(enable: boolean) { + if (this.gesture) { + this.gesture.enable(enable); + } else if (enable) { + this.initSwipeToClose(); + } + } + constructor() { prepareOverlay(this.el); } @@ -148,38 +157,43 @@ export class Modal implements ComponentInterface, OverlayInterface { await present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation, this.presentingElement); - const mode = getIonMode(this); - if (this.swipeToClose && mode === 'ios') { - // All of the elements needed for the swipe gesture - // should be in the DOM and referenced by now, except - // for the presenting el - const animationBuilder = this.leaveAnimation || config.get('modalLeave', iosLeaveAnimation); - const ani = this.animation = animationBuilder(this.el, this.presentingElement); - this.gesture = createSwipeToCloseGesture( - this.el, - ani, - () => { - /** - * While the gesture animation is finishing - * it is possible for a user to tap the backdrop. - * This would result in the dismiss animation - * being played again. Typically this is avoided - * by setting `presented = false` on the overlay - * component; however, we cannot do that here as - * that would prevent the element from being - * removed from the DOM. - */ - this.gestureAnimationDismissing = true; - this.animation!.onFinish(async () => { - await this.dismiss(undefined, 'gesture'); - this.gestureAnimationDismissing = false; - }); - }, - ); - this.gesture.enable(true); + if (this.swipeToClose) { + this.initSwipeToClose(); } } + private initSwipeToClose() { + if (getIonMode(this) !== 'ios') { return; } + + // All of the elements needed for the swipe gesture + // should be in the DOM and referenced by now, except + // for the presenting el + const animationBuilder = this.leaveAnimation || config.get('modalLeave', iosLeaveAnimation); + const ani = this.animation = animationBuilder(this.el, this.presentingElement); + this.gesture = createSwipeToCloseGesture( + this.el, + ani, + () => { + /** + * While the gesture animation is finishing + * it is possible for a user to tap the backdrop. + * This would result in the dismiss animation + * being played again. Typically this is avoided + * by setting `presented = false` on the overlay + * component; however, we cannot do that here as + * that would prevent the element from being + * removed from the DOM. + */ + this.gestureAnimationDismissing = true; + this.animation!.onFinish(async () => { + await this.dismiss(undefined, 'gesture'); + this.gestureAnimationDismissing = false; + }); + }, + ); + this.gesture.enable(true); + } + /** * Dismiss the modal overlay after it has been presented. *