Creating a very simple MonoTouch application without the Interface Builder
I admit that I’m not a big fan of the Interface Builder (IB). I find that it either hides what I need to know or fails to help me implement what I what via a GUI. So I’ve decided to take a leaf from Craig Dunn (http://conceptdev.blogspot.com/search/label/monotouch) and avoid some of the hidden magic from IB and manually build some of the controls. However, there isn’t an empty iPhone project so I thought I’d write a quick blog to help me remember what I need to do.
Create a new project
First off create a new project, this will generate the usual set of files, so the next step is to get rid of those of IB files
Clean the project
Delete MainWindow.xib
Add AppDelegate.cs
I like Craig’s clean solution, so do as the man says and add a new class (File->New) AppDelegate
and add the following code snippet;
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace UIWithoutIB
{
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// Create the main window and add the navigation controller as a subview
window = new UIWindow (UIScreen.MainScreen.Bounds);
window.MakeKeyAndVisible ();
return true;
}
// This method is allegedly required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
}
}
Change Main to use only AppDelegate.cs
Remove the partial class used to implement the Application Delegate from Main.cs. Main should look like;
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace UIWithoutIB
{
public class Application
{
static void Main (string[] args)
{
// UIApplication.Main (args); See blog comments from Philippe Laybaert….
UIApplication.Main (args,null,"AppDelegate");
}
}
}
Prevent, Failed to load NSMainNibFile MainWindow
Ok so we’re in the land of Cocoa and we should play nice and say what our Main Window is. But hey I don’t want to, so if you build now you’ll get a strange message, ‘Failed to load NSMainNibFile MainWindow’. The template did a good job and created a MainWindow and filled in some extra “project” details. Since we no longer have MainWindow we should correct this. So make sure you have set your display options to Show all files, and navigate down the bin folders to the info.plist file. Open that and delete the ‘Main nib file base name’ setting.
Load our views
Change the App Delegate to add our views (and controller), or in this case a label control. Change the FinishedLaunching override to;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// Create the main window and add the navigation controller as a subview
window = new UIWindow (UIScreen.MainScreen.Bounds);
UILabel purpleLabel = new UILabel();
purpleLabel.BackgroundColor = UIColor.Purple;
purpleLabel.Text = "Hello none IB World";
purpleLabel.Frame = window.Frame;
window.AddSubview(purpleLabel);
window.MakeKeyAndVisible ();
return true;
}
Run the app
So from here we can add other view-controllers without having to use IB. Having said that, I still use IB to create the odd view, and you can still use those controllers with this method.
A quick note about troubleshooting, I’ve found that if you’ve built with a IB file (xib) you later delete it’s worth asking for a Build->Clean, Build->Rebuild.
Here is another simple way to remove the XIB reference from the project: delete the MainWindow.xib, right-click on the project name, select the menu Options, then IPhone Application and clean the "MainWindow" reference in the "Main Interface File" textbox. You can prevent the "Failed to load NSMainNibFile MainWindow" error by doing so too.
Thanks kentakhy, sounds better than cluttering up the solution with all the files showing
Try cleaning your solution (or removing the bin folder), rebuild and run. The app won\’t run.You have to specify the name of the AppDelegate class in the call to UIApplication.Main():UIApplication.Main (args,null,"AppDelegate");
Philippe, I originally had those extra overloads but took them out and it carried out working. I assumed it was defaulting to looking for something registered as "AppDelegate". I\’m beginning to realise that you have to manually clean more often than I\’m used to. Thanks, edited the code.
This is a great idea! Interface Builder can be a pain. But I think there is an even simpler way to achieve what you want: http://www.alexyork.net/blog/post/Creating-an-empty-MonoTouch-solution-%28with-no-Interface-Builder%29.aspx