Sonali
Sonali

Reputation: 2283

Xamarin Form: Ios Toast Notification

I have created a Toast notification in my Xamarin PCL project. I have created this control using this. As soon as this toast message disappears my app becomes blank. I cannot figure out why? no exception from any where??

In Portable:

namespace ABC
{
        public interface IMessage
        {
            void LongAlert(string message);
            void ShortAlert(string message);
        }
}

In Droid:

public class MessageAndroid : IMessage
    {
        public void LongAlert(string message)
        {
            Toast.MakeText(Application.Context, message, ToastLength.Long).Show();
        }

        public void ShortAlert(string message)
        {
            Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
        }
    }

In Windows 10:

public class ToastNotificationManagerRenderer : IMessage
    {
        public void LongAlert(string message)
        {
            var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
            var toeastElement = notificationXml.GetElementsByTagName("text");
            toeastElement[0].AppendChild(notificationXml.CreateTextNode(message));
            var toastNotification = new ToastNotification(notificationXml);
            ToastNotificationManager.CreateToastNotifier().Show(toastNotification);
        }

        public void ShortAlert(string message)
        {
            var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
            var toeastElement = notificationXml.GetElementsByTagName("text");
            toeastElement[0].AppendChild(notificationXml.CreateTextNode(message));
            var toastNotification = new ToastNotification(notificationXml);
            ToastNotificationManager.CreateToastNotifier().Show(toastNotification);
        }
    }

In Ios:

public class MessageIOS : IMessage
    {
        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();
            }
        }
    }

For Ios: I have tried this plugin also.MessageBarLib. Code same as above in portable but in Ios -

public void ShortAlert(string message)
        {
            MessageBarManager.SharedInstance.ShowMessage("Success", message, MessageType.Success);

        }

But after exiting from above function, my app closes.

Upvotes: 0

Views: 944

Answers (2)

Sonali
Sonali

Reputation: 2283

I tried this for IOS:-

private const int Margin = 30;
private const int Height = 40;
private const int Width = 400;
private NSTimer _timer;

    public void ShowAlert(string message)
    {
        var toast = new MessageIOS();
        toast.Show(UIApplication.SharedApplication.KeyWindow.RootViewController.View, message);
    }
    public MessageIOS()
    {
        _view = new UIView(new CGRect(0, 0, 0, 0))
        {
            BackgroundColor = UIColor.FromRGB(0, 175, 240)
        };
        _view.Layer.CornerRadius = (nfloat)20.0;

        _label = new UILabel(new CGRect(0, 0, 0, 0))
        {
            TextAlignment = UITextAlignment.Center,
            TextColor = UIColor.White
        };
        _view.AddSubview(_label);

    }

    public void Show(UIView parent, string message)
    {
        if (_timer != null)
        {
            _timer.Invalidate();
            _view.RemoveFromSuperview();
        }

        _view.Alpha = (nfloat)0.7;

        _view.Frame = new CGRect(
            (parent.Bounds.Width - Width) / 2,
            parent.Bounds.Height - Height - Margin,
            Width,
            Height);

        _label.Frame = new CGRect(0, 0, Width, Height);
        _label.Text = message;

        parent.AddSubview(_view);

        var wait = 10;
        _timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromMilliseconds(100), delegate {
            if (_view.Alpha <= 0)
            {
                _timer.Invalidate();
                _view.RemoveFromSuperview();
            }
            else
            {
                if (wait > 0)
                {
                    wait--;
                }
                else
                {
                    _view.Alpha -= (nfloat)0.05;
                }
            }
        });
    }

Upvotes: 0

JoeTomks
JoeTomks

Reputation: 3276

Based off of your comments and the code, I suspect that the dismissMessage()' is clearing all of the UIViewControllers that were put onto the stack by the 'PresentingViewController'. I suspect it's a bit of a bug, but If you try:

PresentingViewController.DismissViewController(true, null);

Instead of

alert.DismissViewController(true, null);

I suspect it should work correctly. If not then we could do with knowing a bit more about the design pattern you use in your iOS project to determine if you are presenting 'UIViewControllers' properly.

Upvotes: 0

Related Questions