import { booleanConverter , CSSType , GestureEventData , HorizontalAlignment , isIOS , LayoutBase , StackLayout , VerticalAlignment , View , } from "@nativescript/core" ; import { layout } from "@nativescript/core/utils" ; @ CSSType ( "ModalStack" ) export class ModalStack extends StackLayout { dismissEnabled : string = "true" ; verticalPosition : VerticalAlignment = "middle" ; horizontalPosition : HorizontalAlignment = "center" ; constructor ( ) { super ( ) ; } onLoaded ( ) { super . onLoaded ( ) ; const modalView = this . getChildAt ( 0 ) as LayoutBase ; this . set ( "height" , "100%" ) ; this . set ( "width" , "100%" ) ; this . horizontalAlignment = this . horizontalPosition ; this . verticalAlignment = this . verticalPosition ; this . on ( "tap" , ( evt ) => this . outsideTap ( evt as GestureEventData , modalView ) ) ; } private outsideTap ( args , modal ) { if ( ! booleanConverter ( this . dismissEnabled ) ) { return ; } if ( isIOS ) { const iosMotion = args . ios ; const view = iosMotion . view ; const tapPos = iosMotion . locationInView ( view ) ; const modalFrame = modal . ios . frame ; const insideRect = CGRectContainsPoint ( modalFrame , tapPos ) ; if ( insideRect ) { return ; } } else { const androidMotion = args . android ; const x = androidMotion . getRawX ( ) - layout . toDevicePixels ( this . getLocationOnScreen ( ) . x ) ; const y = androidMotion . getRawY ( ) - layout . toDevicePixels ( this . getLocationOnScreen ( ) . y ) ; const rect = new android . graphics . Rect ( ) ; modal . android . getHitRect ( rect ) ; const insideRect = rect . contains ( x , y ) ; if ( insideRect ) { return ; } } modal . closeModal ( ) ; } }