не удается отобразить alertcontroller, когда страница отображается с помощью PushModalAsync - PullRequest
2 голосов
/ 18 мая 2019

Я пытаюсь показать всплывающее сообщение в Android и iOS из проекта xamarin.forms, использующего Dependency Service. В iOS-проекте сообщение отображается на MainPage или NavigationPage. но когда я перемещаюсь по второй странице при нажатии кнопки с помощью PushModalAsync, сообщение не отображается.

Как я перемещаюсь по странице

public LoginPage()
{
Device.BeginInvokeOnMainThread(() =>
                {
                    CustomToast.LongMessage("Hiiiiii");  // Message shown
                });

 Navigation.PushModalAsync(new RegisterPage());   //Doesn't show
//var reg = new RegisterPage();
//Application.Current.MainPage = reg;  // toast shown here
}

Код для alertController в iOS:

        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)
        {
            try
            {
                if (alert == null && alertDelay == null)
                {
                    alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            DismissMessage();
                        });
                    });

                    Device.BeginInvokeOnMainThread(() =>
                    {
                        try
                        {
                            alert = UIAlertController.Create("", message, UIAlertControllerStyle.ActionSheet);
                            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
                        }
                        catch (Exception ex)
                        {
                            var Error = ex.Message;
                        }                        
                    });
                }
            }
            catch (Exception ex)
            {
                TraceLog("Message iOS ShowAlert : " + ex.Message);
            }
        }

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

И я вызываю это из моего конструктора страницы регистрации

Device.BeginInvokeOnMainThread(() =>
                {
                    CustomToast.LongMessage("Hiiiiii");
                });

Он никуда не уходит, но и не отображается. Может ли кто-нибудь предложить какой-нибудь совет?

1 Ответ

1 голос
/ 20 мая 2019

Это потому, что RegisterPage является представленной страницей на вашем LoginPage, UIApplication.SharedApplication.KeyWindow.RootViewController, этот код не может получить правильный контроллер представления для RegisterPage. Он только что представил лист действий на предыдущей странице, но ваше приложение достигло новой страницы, тогда этот Тост может быть показан на экране. Во-первых, вы должны узнать верхнюю страницу в окне:

UIViewController topViewControllerWithRootViewController(UIViewController rootViewController)
{
    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);
    }
    return rootViewController;
}

Во-вторых, настройте свой код представления следующим образом:

Device.BeginInvokeOnMainThread(() =>
{
    try
    {
        alert = UIAlertController.Create("", messages, UIAlertControllerStyle.ActionSheet);
        topViewControllerWithRootViewController(UIApplication.SharedApplication.KeyWindow.RootViewController).PresentViewController(alert, true, null);
    }
    catch (Exception ex)
    {
        var Error = ex.Message;
    }
});

Наконец, вы можете показать свой тост, используя Navigation.PushModalAsync(new RegisterPage());

...