August 30, 2011

Custom Animations for the UINavigationController in MonoTouch

Pushing and popping controllers in a standard UINavigationController is a frequent activity when navigating an iOS app. The transition from controller to controller on the navigation stack may be optionally animated. Unfortunately, there's little choice regarding the animation itself. The developer determines whether or not the default right-to-left (push) or left-to-right (pop) effect is rendered by setting a boolean.

In some areas of my UI I wanted more control over the animations in my navigation stack. This thread on Stack Overflow was a great place to start. I ported some of the Objective-C code I found to C# extension methods as follows:
//Allows a UINavigationController to push using a custom animation transition
public static void PushControllerWithTransition(this UINavigationController 
  target, UIViewController controllerToPush, 
  UIViewAnimationOptions transition)
{
  UIView.Transition(target.View, 0.75d, transition, delegate() {
    target.PushViewController(controllerToPush, false);
  }, null);
}
		
//Allows a UINavigationController to pop a using a custom animation 
public static void PopControllerWithTransition(this UINavigationController 
  target, UIViewAnimationOptions transition)
{
  UIView.Transition(target.View, 0.75d, transition, delegate() {
    target.PopViewControllerAnimated(false);
  }, null);			
}
With these extensions in scope, moving between controllers with a flip animation is now as trivial as this:
//Pushing someController to the top of the stack
NavigationController.PushControllerWithTransition(someController, 
  UIViewAnimationOptions.TransitionFlipFromLeft);

//Popping the current controller off the top of the stack
NavigationController.PopControllerWithTransition(
  UIViewAnimationOptions.TransitionFlipFromRight);

August 19, 2011

Scheduling Local Notifications in MonoTouch

iOS 4 introduced local notifications, allowing apps to communicate brief text messages to users. In particular, a scheduled local notification can reach a user whether the app is running in the foreground, in the background or not running at all. While not as versatile as push notifications, scheduled local notifications can be helpful when an app needs to set-up predetermined alarms or reminders. Each app can have a total of 64 simultaneous scheduled local notifications (use them wisely so as to not annoy your users). Below is an example of how to schedule a UILocalNotification using MonoTouch:
//Schedule one minute from the time of execution with no repeat
UILocalNotification notification = new UILocalNotification{
  FireDate = DateTime.Now.AddMinutes(1),
  TimeZone = NSTimeZone.LocalTimeZone,
  AlertBody = "This is your scheduled local notification!",
  RepeatInterval = 0
};
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
You might notice that scheduled local notifications are automatically displayed when the current date/time surpasses our FireDate and the app is in the background or not running at all. However, when the app is in the foreground local notifications are seemingly ignored. This is by design. If the app is in the foreground you are in charge of responding to scheduled local notifications by overriding the ReceivedLocalNotification method as follows:
public override void ReceivedLocalNotification(UIApplication application, 
  UILocalNotification notification)
{
  //Do something to respond to the scheduled local notification
  UIAlertView alert = new UIAlertView("Notification Test", 
  notification.AlertBody, null, "Okay");
  alert.Show();
}