I'm still learning the ropes in Xamarin ios and have implemented a side drawer based on the following example Monotouch.SlideoutNavigation. In this tutorial,there's a main view controller class which then assigns a main navigation controller and a side menu.
The drawer menu options are fed into the menu class while the "home screen/first screen" is passed onto the main navigation controller class which is a subclass of a UINavigationController class.
My home screen is a tabcontroller class and I'm trying to make a reference to the navigation controller inside this class but it always returns null.
These are the two challenges I'm facing:
The navigation controller inside the tab controller and single tab view controllers is always null
The titles of my individual tab controller classes are not shown on the navigation bar.
Here's the AppDelegate class :
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
public SlideoutNavigationController Menu { get; private set; }
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
Menu = new SlideoutNavigationController ();
var tabBarController = GetViewController (Main, "MainTabBarController");
Menu.MainViewController = new MainNavigationController (tabBarController, Menu);
Menu.MenuViewController = new MenuNavigationController (new MenuControllerLeft (), Menu) { NavigationBarHidden = true };
SetRootViewController (Menu, false);
return true;
}
}
The MainTabController class
public partial class MainTabBarController : UITabBarController
{
UINavigationItem titleRequest,titleHome,titleSell;
public MainTabBarController (IntPtr handle) : base (handle)
{
//Create an instance of our AppDelegate
appDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
//Get an instance of our Main.Storyboard
var mainStoryboard = appDelegate.Main;
var tab1 = appDelegate.GetViewController (mainStoryboard, "Tab1");
var tab2 = appDelegate.GetViewController (mainStoryboard, "Tab2");
var tab3 = appDelegate.GetViewController (mainStoryboard, "Tab3");
var tabs = new UIViewController[] {
tab1, tab2, tab3
};
this.SelectedIndex = 1;
ViewControllers = tabs;
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
if(this.SelectedIndex == 0)
{
titleRequest = new UINavigationItem ("TAB 1");
this.NavigationController.NavigationBar.PushNavigationItem (titleRequest, true); // NavigationController here is null
}else if(this.SelectedIndex == 1)
{
titleHome = new UINavigationItem ("TAB 2");
this.NavigationController.NavigationBar.PushNavigationItem (titleHome, true);
}else{
titleSell = new UINavigationItem ("TAB 3");
this.NavigationController.NavigationBar.PushNavigationItem (titleSell, true);
}
}
}
The MainNavigation controller class
public class MainNavigationController : UINavigationController
{
public MainNavigationController(UIViewController rootViewController, SlideoutNavigationController slideoutNavigationController)
: this(rootViewController, slideoutNavigationController,
new UIBarButtonItem(UIImage.FromBundle("icon_sidemenu.png"), UIBarButtonItemStyle.Plain, (s, e) => {}))
{
}
public MainNavigationController(UIViewController rootViewController, SlideoutNavigationController slideoutNavigationController, UIBarButtonItem openMenuButton)
: base(rootViewController)
{
openMenuButton.Clicked += (s, e) => slideoutNavigationController.Open(true);
rootViewController.NavigationItem.LeftBarButtonItem = openMenuButton;
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.Delegate = new NavigationControllerDelegate();
InteractivePopGestureRecognizer.Enabled = true;
}
public override void PushViewController(UIViewController viewController, bool animated)
{
// To avoid corruption of the navigation stack during animations disabled the pop gesture
if (InteractivePopGestureRecognizer != null)
InteractivePopGestureRecognizer.Enabled = false;
base.PushViewController(viewController, animated);
}
private class NavigationControllerDelegate : UINavigationControllerDelegate
{
public override void DidShowViewController(UINavigationController navigationController, UIViewController viewController, bool animated)
{
// Enable the gesture after the view has been shown
navigationController.InteractivePopGestureRecognizer.Enabled = true;
}
}
}
Edit - Results after making changes suggested by Jason below
Could someone help me see what I'm doing wrong.
do this in AppDelegate:
tabs = new UITabBarController();
tabs.ViewControllers = new UIViewController[]{
new UINavigationController(new UIViewController() { Title = "Tab A" }),
new UINavigationController(new UIViewController() { Title = "Tab B" }),
new UINavigationController(new UIViewController() { Title = "Tab C" })
};
Menu = new SlideoutNavigationController();
Menu.MainViewController = new MainNavigationController(tabs, Menu);
Menu.MenuViewController = new MenuNavigationController(new DummyControllerLeft(), Menu) { NavigationBarHidden = true };
I finally found a work around this. For anyone using Dillan's solution and has a TabBarController class as one of the Menu classes, here's how I got it to work.
I wrapped the TabBarController class in a NavigationController,apart from the MainNavigationController class. I didn't have to wrap each tab in it's own NavigationController after this.That solves the null reference to the NavigationController inside the TabBarController class
To solve the titles being obscured inside each tab, I found a simple solution:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
try{
this.ViewControllerSelected += (object sender, UITabBarSelectionEventArgs e) => {
switch(TabBar.SelectedItem.Title)
{
case"TAB 1" :
Title = "TAB 1";
break;
case "TAB 2":
Title = "TAB 2";
break;
default:
Title = "TAB 3";
break;
}
};
}catch(Exception e)
{
Console.WriteLine (e.Message);
}
}
Related
I have form in xamarin.forms and I want to show a popup message when users click on the nav bar button if there are pending data to save. I found this example but it doesn't not working on Xamarin.Forms 5.0
Any idea of how to do it?
I did a quick test on this you can refer to it.
First, I create a contentpage and set CustomBackButtonAction, EnableBackButtonOverride to add navigate method:
public partial class TestPage5 : ContentPage
{public Action CustomBackButtonAction { get; set; }
public static readonly BindableProperty EnableBackButtonOverrideProperty = BindableProperty.Create(
nameof(EnableBackButtonOverride),
typeof(bool),
typeof(TestPage5),
false
);
public bool EnableBackButtonOverride {
get { return (bool)GetValue(EnableBackButtonOverrideProperty); }
set { SetValue(EnableBackButtonOverrideProperty, value); }
}
public TestPage5()
{
InitializeComponent();
EnableBackButtonOverride = true;
CustomBackButtonAction = async () => { var result = await DisplayAlert("Alert", "Are you Sure?", "Yes", "No");
if (result)
{ await Navigation.PopAsync(true); } };
}
}
Then create renderer on ios while override OnOptionsItemSelected on android:
ios(create a new backbutton and override):
[assembly:ExportRenderer(typeof(TestPage5),typeof(MyRenderer))]
namespace My_Forms_Test3.iOS
{
public class MyRenderer:Xamarin.Forms.Platform.iOS.PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (((TestPage5)Element).EnableBackButtonOverride)
{
SetButton();
}
}
private void SetButton()
{
var backbuttonimg = UIImage.FromBundle("backarrow.png");
backbuttonimg = backbuttonimg.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
var backbutton = new UIButton(UIButtonType.Custom)
{ HorizontalAlignment=UIControlContentHorizontalAlignment.Left,
TitleEdgeInsets=new UIEdgeInsets(11.5f,15f,10f,0f),
ImageEdgeInsets=new UIEdgeInsets(1f,8f,0f,0f)};
backbutton.SetTitle("Back", UIControlState.Normal);
backbutton.SetTitleColor(UIColor.White, UIControlState.Normal);
backbutton.SetTitleColor(UIColor.LightGray, UIControlState.Highlighted);
backbutton.Font = UIFont.FromName("HelveticaNeue", (nfloat)17);
backbutton.SetImage(backbuttonimg, UIControlState.Normal);
backbutton.SizeToFit();
backbutton.TouchDown += (sender, e) =>
{
if (((TestPage5)Element)?.CustomBackButtonAction != null)
{
((TestPage5)Element)?.CustomBackButtonAction.Invoke();
}
};
backbutton.Frame = new CoreGraphics.CGRect(0, 0, UIScreen.MainScreen.Bounds.Width / 4,
NavigationController.NavigationBar.Frame.Height);
var buttoncontainer = new UIView(new CoreGraphics.CGRect(0, 0, backbutton.Frame.Width, backbutton.Frame.Height));
buttoncontainer.AddSubview(backbutton);
var fixspace = new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace)
{ Width = -16f };
var backbuttonitem = new UIBarButtonItem("", UIBarButtonItemStyle.Plain, null) { CustomView = backbutton };
NavigationController.TopViewController.NavigationItem.LeftBarButtonItems = new[] { fixspace, backbuttonitem };
}
}
}
android:
add following on main activity:
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
//important to trigger OnOptionItemSelected
Android.Support.V7.Widget.Toolbar toolbar
= this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
also in mainactivity.cs:
public override bool OnOptionsItemSelected(IMenuItem item)
{
// check if the current item id
// is equals to the back button id
if (item.ItemId == 16908332) // xam forms nav bar back button id
{
// retrieve the current xamarin
// forms page instance
var currentpage = (TestPage5)Xamarin.Forms.Application.Current.
MainPage.Navigation.NavigationStack.LastOrDefault();
// check if the page has subscribed to the custom back button event
if (currentpage?.CustomBackButtonAction != null)
{
// invoke the Custom back button action
currentpage?.CustomBackButtonAction.Invoke();
// and disable the default back button action
return false;
}
// if its not subscribed then go ahead
// with the default back button action
return base.OnOptionsItemSelected(item);
}
else
{
// since its not the back button
//click, pass the event to the base
return base.OnOptionsItemSelected(item);
}
}
//android Hardware back button event
public override void OnBackPressed()
{
// this is really not necessary, but in Android user has both Nav bar back button
// and physical back button, so its safe to cover the both events
var currentpage = (BaseContentPage)Xamarin.Forms.Application.Current.
MainPage.Navigation.NavigationStack.LastOrDefault();
if (currentpage?.CustomBackButtonAction != null)
{
currentpage?.CustomBackButtonAction.Invoke();
}
else
{
base.OnBackPressed();
}
}
Here is the full blog I have written which handles the same,
Android:
I have used NavigationPage Renderer to achieve this functionality in android
Android Implementtion
iOS:
I have used Page Renderer to achieve this functionality in iOS
public class CustomPageRenderer:PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (Element != null && Element is BasePage basePage && basePage.BindingContext != null &&
basePage.BindingContext is BaseViewModel baseViewModel)
{
SetCustomBackButton(baseViewModel);
}
}
private void SetCustomBackButton(BaseViewModel baseViewModel)
{
UIButton btn = new UIButton();
btn.Frame = new CGRect(0, 0, 50, 40);
btn.BackgroundColor = UIColor.Clear;
btn.TouchDown += (sender, e) =>
{
// Whatever your custom back button click handling
baseViewModel.BackPressedAction?.Invoke(false);
};
//var views = NavigationController?.NavigationBar.Subviews;
NavigationController?.NavigationBar.AddSubview(btn);
}
}
Note:
Do create BackPressedAction Action in your base view model to capture the back press event
i am trying to create a transaction between two view controllers on xamarin.ios (i am not using the navigation controllers but the viewcontrollers), i would like that when the swipe gesture is in progress it appears under the view controller that moves another side viewcontroller (the target one) I'm trying to emulate the classic "go back" gesture of ios present both on the system itself and on whatsapp. I had already posted and I had partially solved, managing the scrolling animation, but for the second view controller nothing to do :(
my code...
private void InteractiveTransitionRecognizerActionWithoutIndex(UIScreenEdgePanGestureRecognizer sender, UIView View, string x)
{
//Contiene un valore numerico che varia in base allo stato della gesture
var percento = sender.TranslationInView(View).X * 100 / sender.View.Bounds.Size.Width;
var storyboard = UIStoryboard.FromName("Main", null);
// var viewController = storyboard.InstantiateViewController(x);
//Quando la gesture rileva una variazione
if (sender.State == UIGestureRecognizerState.Changed)
{
var minTransform = CGAffineTransform.MakeTranslation(sender.TranslationInView(View).X, 0); //*2 = piu rapido
var maxTransform = CGAffineTransform.MakeTranslation(sender.TranslationInView(View).X, 0);
View.Transform = true ? minTransform : maxTransform;
UIView.Animate(0.1, 0, UIViewAnimationOptions.CurveEaseInOut,
() =>
{
View.Transform = true ? maxTransform : minTransform;
//???
},
null
);
If you are using storyboards and familiar with segues. To define a custom transition animation you will have to configure your segue as follows:
Then in the first view controller you can override the PrepareForSegue method:
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue(segue, sender);
var destinationVC = segue.DestinationViewController as SecondViewController;
destinationVC.Callee = this;
destinationVC.TransitioningDelegate = new CustomTransitioningDelegate(sender as UIView);
destinationVC.ModalPresentationStyle = UIModalPresentationStyle.Custom;
}
public class CustomTransitioningDelegate: UIViewControllerTransitioningDelegate
{
readonly UIView _animationOrigin;
public CustomTransitioningDelegate(UIView animationOrigin)
{
_animationOrigin = animationOrigin;
}
public override IUIViewControllerAnimatedTransitioning GetAnimationControllerForPresentedController(UIViewController presented, UIViewController presenting, UIViewController source)
{
var customTransition = new GrowTransitionAnimator(_animationOrigin);
return customTransition;
}
}
The animations are defined in a class that inherit from UIViewControllerAnimatedTransitioning.
public class GrowTransitionAnimator : UIViewControllerAnimatedTransitioning
{
readonly UIView _animationOrigin;
public GrowTransitionAnimator(UIView animationOrigin)
{
_animationOrigin = animationOrigin;
}
public override async void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
{
// The animation here
}
public override double TransitionDuration(IUIViewControllerContextTransitioning transitionContext)
{
return 0.3;
}
}
Inside my application I have LoginView and after that MainView which is MvxTabBarViewController with two tabs. Here is my code for MainView:
public class MainView : MvxTabBarViewController<MainViewModel>
{
private bool _constructed;
public MainView()
{
_constructed = true;
// need this additional call to ViewDidLoad because UIkit creates the view before the C# hierarchy has been constructed
ViewDidLoad();
}
public override void ViewDidLoad()
{
if (!_constructed)
return;
base.ViewDidLoad();
Title = "SampleTabs";
View.BackgroundColor = UIColor.Red;
var viewControllers = new List<UIViewController>();
viewControllers.Add(CreateTabFor("Second", ViewModel.TabEvents, 0));
viewControllers.Add(CreateTabFor("First", ViewModel.TabDashboard, 1));
ViewControllers = viewControllers.ToArray();
CustomizableViewControllers = new UIViewController[] { };
// SelectedViewController = ViewControllers[1];
}
private UIViewController CreateTabFor(string title, IMvxViewModel viewModel, int index)
{
var controller = new UINavigationController();
var screen = this.CreateViewControllerFor(viewModel) as UIViewController;
screen.Title = title;
// screen.TabBarItem = new UITabBarItem(title, null, index);
screen.TabBarItem = new UITabBarItem(UITabBarSystemItem.Search, index);
controller.PushViewController(screen, false);
controller.NavigationBarHidden = true;
return controller;
}
}
Problem is with tab items, I can't change it to second after initial tab is showed. Tabs are simple with only background color change. Any help is welcome.
Fixed! Problem was with core core not with tab view.
I'm trying to create my first iOS project. I have quite well experiences with C#. I receive data with categories and articles. But I don't know, how many subcategories I will get, before the articles will be listed. The browsing though the subcategories should be done via TableView. When a User clicks a category, the subcategories (level 1) should be displayed in a tableView. Then, after touching a subcategory, the subcategories (level 2) of present should be displayed (and so on). Lastly, when there are no further subcategories, the article-list should be displayed. After touching one article, a new ViewController with the article-data should be displayed.
My question is, how to handle the navigation through the subcategories and creating segues or sth. like that. I know, that I can't use storyboard for this, because I don't know the number of subcategories and they also differ.
How can I achieve this dynamic navigation? Can you give me an example? I know how to populate data to the tableView. Only the dynamic navigation is the problem.
I now have a solution. Can someone please check, if I am doing it correctly not that I don't violate programming patterns or guidelines.
In short: In TableSource-Class I access the Storyboard and dynamically create and show the same Controller which actually is presented. But before presenting the new one, I declare an other source-class. So the TableView is used for displaying Addressbooks and Addresscards, the UIViewController is used for displaying the carddata. These two controllers are connected via segue.
Here are my Controller and both Source-Classes:
AddressbooksController.cs
public AddressbooksController (IntPtr handle) : base (handle)
{
displayModel = "addressbooks";
}
private void loadAddressbooks()
{
var AppDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
addressbooks = AppDelegate.api.DeserializeEntities<YAddressbook>(Task.Run(async () => await AppDelegate.api.Get("Yaddressbooks")).Result);
}
public void loadAddresscards()
{
var AppDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
addresscards = AppDelegate.api.DeserializeEntities<Ycard>(Task.Run(async () => await AppDelegate.api.Get("Ycards")).Result);
}
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue(segue, sender);
// do first a control on the Identifier for your segu
if (segue.Identifier.Equals("segueShowAddress"))
{
var viewController = (AddresscardController)segue.DestinationViewController;
viewController.card = Card2Display;
}
}
public override void ViewDidLoad()
{
if (displayModel == "addressbooks")
{
loadAddressbooks();
tableView.Source = new AddressbooksTableSource(addressbooks.data, this);
this.NavigationController.Title = "Addressbücher";
}
else if (displayModel == "addresscards")
{
loadAddresscards();
tableView.Source = new AddresscardsTableSource(addresscards.data, this);
this.NavigationController.
}
base.ViewDidLoad();
}
AddressbooksTableSource
public class AddressbooksTableSource: UITableViewSource
{
private List<YAddressbook> addressbooks;
private string cellIdentifier = "AddressbooksCell";
private UINavigationController navigationController;
public AddressbooksTableSource(List<YAddressbook> books, AddressbooksController ab)
{
addressbooks = books;
this.navigationController = ab.ParentViewController as UINavigationController;
Console.WriteLine(ab.displayModel);
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
Console.WriteLine("Row selected" + addressbooks[indexPath.Row].displayname);
UIStoryboard Storyboard = UIStoryboard.FromName("Main", null);
AddressbooksController newab = Storyboard.InstantiateViewController("AddressbooksViewController") as AddressbooksController;
newab.displayModel = "addresscards";
navigationController.PushViewController(newab, true);
tableView.DeselectRow(indexPath, true);
}
....
}
AddresscardsTableSource
public class AddresscardsTableSource: UITableViewSource
{
private List<Ycard> addresscards;
UINavigationController navigationController;
AddressbooksController ab;
string cellIdentifier = "AddresscardCell";
public AddresscardsTableSource(List<Ycard> cards, AddressbooksController vc)
{
addresscards = cards;
navigationController = vc.ParentViewController as UINavigationController;
ab = vc;
//navigationController = tableview;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
Console.WriteLine("Row selected" + addresscards[indexPath.Row].carddata);
//UIStoryboard Storyboard = UIStoryboard.FromName("Main", null);
ab.Card2Display = addresscards[indexPath.Row];
ab.PerformSegue("segueShowAddress", indexPath);
//AddresscardController ab = Storyboard.InstantiateViewController("AddresscardViewController") as AddressbooksController;
//ab.TableView.Source = this;
//navigationController.PushViewController(ab, true);
tableView.DeselectRow(indexPath, true);
}
.....
}
It works. But am I doing it correctly? Thanks
When loading the sample code in Xamarin Studio, the app runs as expected.
Xamarin.com Local Notifications Sample Code
But when starting a new single view project, I tried using bits of the code that seemed necessary. The viewcontroller class is structured differently, than in the sample code, on a new project.
ViewController.cs
using System;
using UIKit;
using Foundation;
namespace TestProject1
{
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 DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
partial void ButButton_TouchUpInside (UIButton sender)
{
var notification = new UILocalNotification();
notification.FireDate = NSDate.FromTimeIntervalSinceNow(5);
notification.AlertAction = "Test";
notification.AlertBody = "Test Text";
notification.ApplicationIconBadgeNumber = 1;
notification.SoundName = UILocalNotification.DefaultSoundName;
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
//throw new NotImplementedException ();
}
}
}
AppDelegate.cs
using Foundation;
using UIKit;
namespace TestProject1
{
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
private ViewController viewController;
private UIWindow window;
public override UIWindow Window {
get;
set;
}
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
viewController = new ViewController();
window = new UIWindow (UIScreen.MainScreen.Bounds);
viewController = new ViewController ();
window.RootViewController = viewController;
window.MakeKeyAndVisible ();
//if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
var notificationSettings = UIUserNotificationSettings.GetSettingsForTypes (
UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, null
);
application.RegisterUserNotificationSettings (notificationSettings);
//}
if (launchOptions != null)
{
// check for a local notification
if (launchOptions.ContainsKey(UIApplication.LaunchOptionsLocalNotificationKey))
{
var localNotification = launchOptions[UIApplication.LaunchOptionsLocalNotificationKey] as UILocalNotification;
if (localNotification != null)
{
UIAlertController okayAlertController = UIAlertController.Create (localNotification.AlertAction, localNotification.AlertBody, UIAlertControllerStyle.Alert);
okayAlertController.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Default, null));
viewController.PresentViewController (okayAlertController, true, null);
// reset our badge
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
}
}
}
return true;
}
public override void ReceivedLocalNotification(UIApplication application, UILocalNotification notification)
{
// show an alert
UIAlertController okayAlertController = UIAlertController.Create (notification.AlertAction, notification.AlertBody, UIAlertControllerStyle.Alert);
okayAlertController.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Default, null));
viewController.PresentViewController (okayAlertController, true, null);
// reset our badge
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
}
}
}
In the sample project, the only difference is ViewController is declared with no parameters: public ViewController { }. If I add that code, the app complies and runs. The notifications fires and shows the badge, but never shows appears within the app.
Instead of trying to rig the code on a new project, how do you properly declare: viewController = new ViewController(); with a IntPtr parameter?
Thanks in advance!
Instead of trying to use attach the alert to the ViewController as shown in the demo code, use UIAlertView.
public override void ReceivedLocalNotification(UIApplication application, UILocalNotification notification)
{
UIAlertView alert = new UIAlertView () { Title = notification.AlertAction, Message = notification.AlertBody };
alert.AddButton("OK");
alert.Show ();
// CLEAR BADGES
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
}