Sunday, 18 October 2009

MonoTouch sans Interface Builder

I have nothing against Interface Builder per se, but as I've said before when developing with Visual Studio I shun the design surface (if you've used the Xaml preview feature prior to 2010 you'll understand why). I also think you get a better understanding of your environment (and a greater ability to customize your UI) if you can create it in code.

But for new MonoTouch developers it can be difficult to figure out how to create something in code. I've just been through this adding a UISegmentedControl to the Monospace app... here are my (rather obvious) suggestions:
  • Autocomplete/Intellisense™ - the easiest and most obvious thing to try is reading through the properties and methods available to you via MonoDevelop. I got the UITabBarController (mostly) working this way.
  • Interface Builder - look closely at the IB Inspector windows to get some ideas about the properties exposed.
  • XIB file - further to the Inspector windows, the XIB file (in its weird XMLish format) might also give you some hints. Obviously this means you need to 'draw' the control/s in IB, but just roughly for inspiration...
  • Objective-C references - for now most search results will be from Objective-C devs; it isn't hard to decode them (usually) so don't be dissuaded because it "looks different" :)
    Try Miguel's Rosetta stone decoder for Objective-C classes/properties → MonoTouch
  • MonoTouch docs - last but not least, the documentation will help you. Bookmark it now.
XIB and Inspector


UISegmentedControl in c#
// Don't forget your using statements 
// this example uses MonoTouch.MapKit
// as well as UIKit and Foundation
var segmentedControl = new UISegmentedControl();
segmentedControl.Frame = new RectangleF(20, 350, 282,44);
segmentedControl.InsertSegment("Map", 0, false);
segmentedControl.InsertSegment("Satellite", 1, false);
segmentedControl.InsertSegment("Hybrid", 2, false);
segmentedControl.SelectedSegment = 0;
segmentedControl.ControlStyle = UISegmentedControlStyle.Plain;

segmentedControl.ValueChanged += delegate {
if (segmentedControl.SelectedSegment == 0)
mapView.MapType = MonoTouch.MapKit.MKMapType.Standard;
else if (segmentedControl.SelectedSegment == 1)
mapView.MapType = MonoTouch.MapKit.MKMapType.Satellite;
else if (segmentedControl.SelectedSegment == 2)
mapView.MapType = MonoTouch.MapKit.MKMapType.Hybrid;
};
// And further down the code, don't forget to Add it!
this.View.AddSubview(segmentedControl);

5 comments:

  1. Hello Craig,

    A few days ago I posted a Rosetta stone document that can be used to translate Objective-C expressions into their equivalent C# ones:

    http://tirania.org/tmp/rosetta.html

    ReplyDelete
  2. Craig, I see that I need to set controller.NavigationBar.BarStyle to UIBarStyle.Default to make the nav bar gray, but what do I have to set so the UITabBar itself is the default gray?

    ReplyDelete
  3. Mike, I'm not sure UITabBar has a grey version -- I've only ever seen it in black.

    You got me curious; a quick google turned up these links... the first one might help you make a grey TabBar, the other two are just for fun

    Custom colors in UITabBar

    UITabBar with a Custom Background

    Preventing a UITabBar from applying a gradient to its icon images

    ReplyDelete
  4. Craig -

    Thanks for posting these excellent examples, it's really helping me get started with MonoTouch.

    I've added a ViewController class file and I want to create a search form on it. I can add controls on it such as a UILabel, but I want to format the layout. What's the best way of doing this with the UIKit? Should I use UITableView with UITableViewCells to hold each row of the form?

    cheers,
    Steve

    ReplyDelete
  5. Steve,

    As you've stated, the most 'basic' way to build a form is just to use a UIView as a Canvas and start dragging controls on -- but then you do have a lot of formatting to make it "look nice" (adhering to the UI guidelines). So unless you've got a really complex/specific/non-standard layout in mind, the UITableView is a nice alternative.

    See Apple's doco on Table View Cells (specifically, scroll down to the The Technique for Static Row Content section). That's one way to lay-out a form, and you'll see it a LOT in the built-in applications: the Contacts form is a good example. You don't have to draw all the cells in IB either, you can create them in code.

    Before you go down that route I would strongly recommend you also give Miguel's Dialog project (example) a try for a very neat, MonoTouch/C# specific way to construct forms (and inputs). I'm not sure how 'style-able/customizable' the cells are in Miguel's solution (apologies Miguel - I haven't played with it enough yet!) but it would definitely simplify the creation of the majority of forms.

    Finally - I'll just throw this in - you've mentioned a 'search form', so is there any reason why you can't express it with a single Search Bar? iPhone users are most used to seeing search in that format (from Maps and Mail to the core OS Search feature). I realise you might have 'advanced options' or something in mind -- but simplicity is the key to successful iPhone UIs so it's worth considering.

    ReplyDelete