0

I am working in xamarin.forms project and I am stuck at a problem.

I want the main screen to remain enabled whenever UIAlertController(in android terms Toast) is shown. Here for me both the things are important.

When showing the alert, buttons from the background view should be clickable. And because an important message needs to be shown, the alert should also appear in parallel for given time.

In android, Toast does not interfere with the user interaction on main screen. Can I have same working thing in iOS ?

Here is what I have tried in my dependency service.

void ShowAlert(string message, double seconds)
        {
            try
            {
                if (alert == null && alertDelay == null)
                {
                    alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                           DismissMessage();
                        });
                    });

                    Device.BeginInvokeOnMainThread(() =>
                    {
                        try
                        {
                            alert = UIAlertController.Create("", message, UIAlertControllerStyle.Alert);
                            alert.View.UserInteractionEnabled = true;

                            topViewControllerWithRootViewController(UIApplication.SharedApplication.KeyWindow.RootViewController).PresentViewController(alert, true, () =>
                            {
                                UITapGestureRecognizer tap = new UITapGestureRecognizer(() => { });   // I have tried this but nothing happens
                                alert.View.Superview.Subviews[0].AddGestureRecognizer(tap);
                            });
                        }
                        catch (Exception ex)
                        {
                            var Error = ex.Message;
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                var Error = ex.Message;
            }
        }

        void DismissMessage()
        {
            if (alert != null)
            {
                alert.DismissViewController(true, null);
                alert = null;
            }
            if (alertDelay != null)
            {
                alertDelay.Dispose();
                alertDelay = null;
            }
        }

        UIViewController topViewControllerWithRootViewController(UIViewController rootViewController)
        {
            try
            {
                if (rootViewController is UITabBarController)
                {
                    UITabBarController tabBarController = (UITabBarController)rootViewController;
                    return topViewControllerWithRootViewController(tabBarController.SelectedViewController);
                }
                else if (rootViewController is UINavigationController)
                {
                    UINavigationController navigationController = (UINavigationController)rootViewController;
                    return topViewControllerWithRootViewController(navigationController.VisibleViewController);
                }
                else if (rootViewController.PresentedViewController != null)
                {
                    UIViewController presentedViewController = rootViewController.PresentedViewController;
                    return topViewControllerWithRootViewController(presentedViewController);
                }
            }
            catch (Exception)
            {
            }
            return rootViewController;
        }

Ketan P
  • 4,259
  • 3
  • 30
  • 36
Ruhika
  • 67
  • 7
  • @Ketan P, Kindly suggest me a solution as well. thanks – Ruhika Jun 10 '19 at 12:12
  • have you checked the workaround in this thread : https://stackoverflow.com/questions/30075832/how-to-dismiss-uialertcontroller-when-tap-outside-the-uialertcontroller – ColeX Jun 10 '19 at 15:03
  • @ColeXia-MSFT I want exactly opposite. I do not want to dismiss alert when tapped outside of it. If you have observed, in iOS when showing alert background is also fade out that means it is disabled. I want it enabled and the alert as well. Alert will only dismiss after the given time interval in `ShowAlert` method. Otherwise alert and background buttons should be enabled – Ruhika Jun 11 '19 at 04:44

1 Answers1

0

There is no iOS native equivalent of a toast. But, there are many way of doing this as mentioned here: Toast equivalent for Xamarin Forms

One of the many solutions mentioned there will work, and if you are looking for a native solution, you can display an alert that dismisses by itself after a specified time as shown:

    public class MessageIOS
    {
        const double LONG_DELAY = 3.5;
        const double SHORT_DELAY = 2.0;

        NSTimer alertDelay;
        UIAlertController alert;

        public void LongAlert(string message)
        {
            ShowAlert(message, LONG_DELAY);
        }
        public void ShortAlert(string message)
        {
            ShowAlert(message, SHORT_DELAY);
        }

        void ShowAlert(string message, double seconds)
        {
            alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
            {
                dismissMessage();
            });
            alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
        }

        void dismissMessage()
        {
            if (alert != null)
            {
                alert.DismissViewController(true, null);
            }
            if (alertDelay != null)
            {
                alertDelay.Dispose();
            }
        }
    }
Saamer
  • 4,687
  • 1
  • 13
  • 55