I’m just going to come right out and say it: I hate Objective-C. In Introduction to The Objective-C 2.0 Programming Language, Apple writes:

The Objective-C language is a simple computer language designed to enable sophisticated object-oriented programming. Objective-C is defined as a small but powerful set of extensions to the standard ANSI C language. Its additions to C are mostly based on Smalltalk, one of the first object-oriented programming languages. Objective-C is designed to give C full object-oriented programming capabilities, and to do so in a simple and straightforward way.

Apparently, that’s true for plenty of Mac and iPhone developers, but not me. I find Objective-C to be ugly, verbose, and confusing. Interface Builder and the whole Cocoa UI event system also leave me cold. MonoTouch is a life saver. It lets me use C# and .Net idioms to develop native iPhone applications. Yes, you’ll still need a Mac. Currently, MonoTouch is in beta. There are of course a few bugs, but the design is beautiful and the developers very responsive. I especially like how MonoTouch integrates the SDK and .Net type systems and events and implements Objective-C delegates.

OK, enough praise for MonoTouch. The real reason for this post is to publish a simple example of using MonoTouch and C# to use a UITableView in an iPhone app. Though you can use Interface Builder with MonoTouch, this example shows how to use a UITableView programmatically.

This was useful for me to learn how to use UITableView initially without a lot of other code. For more details on building the main application and controller, see the MonoTouch sample programs and tutorials.

You’ll also want to read Apple’s Table View Programming Guide for the iPhone OS and UITableView class reference. They’re really quite good. Consequently, I suggest you learn at least enough about Objective-C, Xcode, and Interface Builder to understand Apple’s developer resources.

Update 10/10/09: Fixed the code display.

Here’s the sample code:

[sourcecode language=”csharp”] /* Copyright (c) 2009, Terry Westley

Copying and distribution of this file, with or without modification, are permitted in any medium without royalty. This file is offered as-is, without any warranty. */

using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Text;

using MonoTouch.Foundation; using MonoTouch.UIKit;

namespace MT_SampleTableView { public class Application { static void Main (string[] args) { UIApplication.Main (args, null, “AppController”); } }

[Register (“AppController”)] public class AppController : UIApplicationDelegate { UIWindow window;

public override bool FinishedLaunching ( UIApplication app, NSDictionary options) { // Create the main view controller var vc = new MainViewController ();

// Create the main window and add main view // controller as a subview window = new UIWindow (UIScreen.MainScreen.Bounds); window.AddSubview(vc.View);

window.MakeKeyAndVisible (); return true; }

// This method is allegedly required in iPhoneOS 3.0 public override void OnActivated ( UIApplication application) { } }

[Register] public class MainViewController : UIViewController { private UITableView tableView; private List list;

public override void ViewDidLoad () { base.ViewDidLoad ();

list = new List() { "Tangerine", "Mango", "Grapefruit", "Orange", "Banana" };

tableView = new UITableView() { Delegate = new TableViewDelegate(list), DataSource = new TableViewDataSource(list), AutoresizingMask = UIViewAutoresizing.FlexibleHeight| UIViewAutoresizing.FlexibleWidth, BackgroundColor = UIColor.Yellow, };

// Set the table view to fit the width of the app. tableView.SizeToFit();

// Reposition and resize the receiver tableView.Frame = new RectangleF ( 0, 0, this.View.Frame.Width, this.View.Frame.Height);

// Add the table view as a subview this.View.AddSubview(tableView);

Console.Write(“If you’re using the simulator, “); Console.WriteLine(“switch to it now.”); }

private class TableViewDelegate : UITableViewDelegate { private List list;

public TableViewDelegate(List list) { this.list = list; }

public override void RowSelected ( UITableView tableView, NSIndexPath indexPath) { Console.WriteLine( “TableViewDelegate.RowSelected: Label={0}”, list[indexPath.Row]); } }

private class TableViewDataSource : UITableViewDataSource { static NSString kCellIdentifier = new NSString (“MyIdentifier”); private List list;

public TableViewDataSource (List list) { this.list = list; }

public override int RowsInSection ( UITableView tableview, int section) { return list.Count; }

public override UITableViewCell GetCell ( UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell ( kCellIdentifier); if (cell == null) { cell = new UITableViewCell ( UITableViewCellStyle.Default, kCellIdentifier); } cell.TextLabel.Text = list[indexPath.Row]; return cell; } } } } [/sourcecode]

Updated: