Beispiel #1
0
        public static async Task <TResult> ShowModal <TViewController, TResult>(
            UIViewController parentViewController,
            TViewController viewController,
            Action <TViewController, Action> dismissSubscriber = null,
            UIModalPresentationStyle presentationStyle         = UIModalPresentationStyle.FormSheet,
            UIModalTransitionStyle transitionStyle             = UIModalTransitionStyle.CoverVertical,
            Action completionHandler = null,
            Func <TViewController, TResult> resultGetter = null,
            bool dismissOnTapOutside = true,
            bool disposeOnFinish     = false
            ) where TViewController : UIViewController
        {
            try {
                if (completionHandler == null)
                {
                    completionHandler = Tools.Lambda.NoOp;
                }

                if (dismissOnTapOutside && presentationStyle.IsIn(UIModalPresentationStyle.FullScreen, UIModalPresentationStyle.OverFullScreen))
                {
                    dismissOnTapOutside = false;
                }

                if (dismissSubscriber == null && dismissOnTapOutside == false)
                {
                    throw new ArgumentException("dismissSubscriber is null and dismissOnTapOutside is effectively false, this will result in an unclosable modal screen");
                }


                var signal = new ManualResetEventSlim();
                viewController.ModalPresentationStyle = presentationStyle;
                viewController.ModalTransitionStyle   = transitionStyle;
                Action dismissModalDialogAction = signal.Set;
                dismissSubscriber(viewController, dismissModalDialogAction);
                var currentPresentedController = parentViewController.FindPresentedViewController();
                if (currentPresentedController != null)
                {
                    parentViewController = currentPresentedController;
                }

                viewController.ProvidesPresentationContextTransitionStyle = true;
                viewController.DefinesPresentationContext = true;
                await parentViewController.PresentViewControllerAsync(viewController, true);

                completionHandler();

                var window = parentViewController.View.Window;
                UITapGestureRecognizerEx tapOutsideGesture = null;
                if (dismissOnTapOutside)
                {
                    tapOutsideGesture = new UITapGestureRecognizerEx(async(x) => {
                        if (x.State == UIGestureRecognizerState.Ended)
                        {
                            var location = x.LocationInView(null);//Passing nil gives us coordinates in the window
                            if (!viewController.View.PointInside(viewController.View.ConvertPointFromView(location, window), null))
                            {
                                //Convert tap location into the local view's coordinate system. If outside, dismiss the view.
                                signal.Set();
                            }
                        }
                    });
                    tapOutsideGesture.NumberOfTapsRequired = 1;
                    tapOutsideGesture.CancelsTouchesInView = false;
                    window.AddGestureRecognizer(tapOutsideGesture);
                }

                await Task.Run(() => signal.Wait());

                if (dismissOnTapOutside)
                {
                    window.RemoveGestureRecognizer(tapOutsideGesture);
                }

                if (!viewController.IsBeingDismissed && parentViewController.ModalViewController == viewController)
                {
                    await viewController.DismissViewControllerAsync(true);
                }
                return(resultGetter == null ? default(TResult) : resultGetter(viewController));
            } finally {
                if (disposeOnFinish)
                {
                    viewController.Dispose();
                }
            }
        }