Building iPad applications using MonoTouch: the UISplitView


First of all, I bow deeply to the people that bring us MonoTouch. It was less than 2 days after the introduction of the iPad and the release of a beta of the iPhone/iPad SDK that a version of MonoTouch (and MonoDevelop) was available that covers the new API.

To build iPad apps, you need a couple of things that are all listed on the MonoTouch iPad page.

I couldn’t wait to build something that used the way bigger UI-surface that the iPad has. The first thing that attracted my attention when I fired up the Interface Builder was the UISplitViewController.
The idea behind the SplitView is that you have some navigation on the left (like a NavigationController, or just a TableViewController) and a data view on the right. That is, only when the display is in landscape mode. As soon as you turn the iPad (the iPad SImulator, of course) to portrait, the left side disappears and all the screen is available to the data view.
That behaviour is entirely taken care of by the UISplitViewController, at least if you stick to the conventions!

I decided to make a simple app with a list of places on the left side, and a map-view on the right:

LandscapePortait version of the UI

The obvious start

When you start a new iPad application from the New Project menu, you get the well-known set-up of files in your project. Double-click the MainWindow.xib to fire up Interface Builder. Then drag the Split View Controller from the Library Window and drop it below the Window object in de MainWindow:
MainWindow

As you can see, you get a lot for free, including stuff you don’t want. Now it gets less obvious. After clicking Cmd-Backspace a thousand times and positioning my cursor everywhere, I had an epiphany. Since the SplitViewController won’t work without two other controllers I had to add something new before I could remove the old!

No kidding, that was really the solution. So I added a UITableViewController, Interface Builder magically removed the default NavigationController, and I added a MKMapView to the view-controller on the right.

This is the result:

SplitView I then added outlets to the AppDelegate for the map, the tableview and the splitview:

Outlets

The less obvious code

To make the controllers react properly when the orientation of the UI changes, you need to override the ShouldAutorotateToInterfaceOrientation() method in each of your controllers. How do you do that?
The first step is to add a class to your project, make it inherit from your controller (a UITableViewController in my case) and override the ShouldAutorotateToInterfaceOrientation() method as below:

public class PlacesController : UITableViewController
{
	public PlacesController ()
	{
	}
 
	public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
	{
		return true;
	}
}

Repeat the step for the second controller:

public class Map : UIViewController
{
	public Map ()
	{
	}
 
	public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
	{
		return true;
	}
}

This should still compile. But it doesn’t work yet.

The even less obvious link from the code to the UI

The objects in the Interface Builder are standard objects. They need to be of the types that we just defined, to make the overridden methods work. See we need to make our own classes known to Interface Builder. That’s done by adding a Register-atribute and overriding the constructor with one that accepts an IntPtr.
The Map class changed in something like this:

[Register("Map")]
public class Map : UIViewController
{
	public Map ()
	{
	}
 
	public Map(IntPtr p) : base(p)
	{
	}
 
	public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
	{
		return true;
	}
}

The final step is setting the right class on the controller. Go to Interface Builder, select the UIViewController (e.g.) in the MainWindow, then go to the Inspector Window and type your classname over the default one:

Inspector

And then it works! The map will re-orientate itself when the iPad is turned, and the Table View appears and disappears.
Of course you want some location data in the table and the map to show the locations when clicked on, but that’s all in the code you can download.

Enjoy making software for a device that makes you need to rethink the way you always made software…!!!

Mmmmh. re-reading that last line, I realize it’s a little hard to read. What I meant was something like Joe Hewitt wrote.

, , , , ,

  1. #1 door ChrisNTR om 30 januari 2010

    Dude,

    Everything in the iPhone SDK 3.2 is under NDA. You might want to remove this ASAP.

    ChrisNTR

  2. #2 door Richard de Zwart om 3 april 2010

    As of today, the SDK is public, so here it is. Fixed the code for the latest version of the SDK.

  3. #3 door CK om 28 juni 2010

    Great post, this just solved a few problems for me so thanks for posting it.

(wordt niet gepubliceerd)