Milen
Milen

Reputation: 8867

How to show alert message from UIViewController using UIAlertController

I'm trying to display message using UIAlertController in my UIViewController. Using VisualStudio 2015 CTP 5...

Used samples from:

http://forums.xamarin.com/discussion/26404/uialertcontroller-question-for-ipad http://www.hjerpbakk.com/blog/2014/11/23/from-uialertview-to-uialertcontroller-using-xamarin-and-async-await https://gist.github.com/Sankra/622e5855f95189e13d77

Based on samples above I have this so far:

public partial class MyViewController : GenericViewController //inherits from UIViewController 
{
   .....
     public async override void ViewDidLoad()
     {
            try
            {

                base.ViewDidLoad();
                //other irrelevant code here
                throw new Exception("Something went wrong");
            }
            catch (Exception ex)
            {
                    int result =   await AlertViewControllerHelper.ShowAlertDialogAsync(this, ex.StackTrace, true); 
            }
     }  
      ........
}

My static helper class:

public static class AlertViewControllerHelper 
{
public static Task<int> ShowAlertDialogAsync(UIViewController parent, string stackTrace, bool debugMode = false)
{

    var taskCompletionSource = new TaskCompletionSource<int>();

    try
    {
        var alert = UIAlertController.Create("Error", stackTrace, UIAlertControllerStyle.ActionSheet);
        if (alert.PopoverPresentationController != null)
        {
            alert.PopoverPresentationController.SourceView = parent.View;
            alert.PopoverPresentationController.SourceRect = parent.View.Bounds;
        }

        alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default,
            a => taskCompletionSource.SetResult(0)));
        if (debugMode)
        {
            alert.AddAction(UIAlertAction.Create("Info", UIAlertActionStyle.Default,
                a => taskCompletionSource.SetResult(1)));
        }

        parent.PresentViewController(alert, true, null);

    }
    catch (Exception ex)
    {               
    }
    return taskCompletionSource.Task;
}

After running the code my error dialogue is not is being displayed. I've completed an example using UIAlertView but so far no luck with UIAlertController (and that's my requirement)

Thanks in advance...

Upvotes: 3

Views: 4813

Answers (2)

Alvin George
Alvin George

Reputation: 14296

using System;
using UIKit;
using System.Threading.Tasks;

namespace Sample
{

public partial class ViewController : UIViewController
{

    public ViewController (IntPtr handle) : base (handle)
    {
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        // Perform any additional setup after loading the view, typically from a nib.

    }

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
        this.InvokingMethod ();

    }

    public static Task<bool> ShowOKCancel (UIViewController parent, string strTitle, string strMsg)
    {
        // method to show an OK/Cancel dialog box and return true for OK, or false for cancel
        var taskCompletionSource = new TaskCompletionSource<bool> ();

        var alert = UIAlertController.Create (strTitle, strMsg, UIAlertControllerStyle.ActionSheet);
        // set up button event handlers
        alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult (true)));
        alert.AddAction (UIAlertAction.Create ("Cancel", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult (false)));
        // show it
        parent.PresentViewController (alert, true, null);

        return taskCompletionSource.Task;
    }

    private async void InvokingMethod ()
    {
        var userClickedOk = await ShowOKCancel (this, "Action Sheet Title", " It is just awesome!");
        // go on to use the result in some way      

        if (userClickedOk) {
            Console.WriteLine ("Clicked on Okay");

        } else {                
            Console.WriteLine ("Clicked on Cancel");
        };
    }

    public override void DidReceiveMemoryWarning ()
    {
        base.DidReceiveMemoryWarning ();
        // Release any cached data, images, etc that aren't in use.
    }
}
}

Upvotes: 0

Milen
Milen

Reputation: 8867

Found solution for this:
1. Pass ParentViewController instead of the current view controller (this)

public partial class MyViewController : GenericViewController //inherits from UIViewController 
{

  .....
 public async override void ViewDidLoad()
 {
        try
        {

            base.ViewDidLoad();
            //other irrelevant code here
            throw new Exception("Something went wrong");
        }
        catch (Exception ex)
        {
            int actionCode = await AlertViewControllerHelper.ShowAlertDialogAsync(ParentViewController, AlertViewControllerHelper.ERRORDESCRIPTION);

            if (actionCode == AlertViewControllerHelper.INFOACTIONCODE)
            {
                await AlertViewControllerHelper.ShowAlertDialogAsync(ParentViewController, string.Format("{0} : {1}", ex.Message, ex.StackTrace), actionCode);
            }
        }   
 }  
  ........
}
  1. Then the Helper method will be implemented like this:

    public static Task<int> ShowAlertDialogAsync(UIViewController parent, string stackTrace, int actionCode = 0)
        {
            bool isDebug = false;
    
    // #if DEBUG
            isDebug = true;
    //#endif
    
           var taskCompletionSource = new TaskCompletionSource<int>();
    
            var alert = UIAlertController.Create(ERROR, stackTrace, UIAlertControllerStyle.Alert);
            if (alert.PopoverPresentationController != null)
            {
                alert.PopoverPresentationController.SourceView = parent.View;
                alert.PopoverPresentationController.SourceRect = parent.View.Bounds;
            }
    
            alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default,
                a => taskCompletionSource.SetResult(0)));
            if (isDebug && actionCode == OKACTIONCODE)
            {
                alert.AddAction(UIAlertAction.Create("Info", UIAlertActionStyle.Default,
                    a => taskCompletionSource.SetResult(1)));
            }
    
            parent.PresentViewController(alert, true, null);
    
            return taskCompletionSource.Task;
        }
    

Upvotes: 3

Related Questions