Mostly MonoTouch with a chance of Other Stuff.

Using LoadNib to Load a View

Ok, so there was a gap between posts. My wife and I have been focusing a lot on renovating our house over the last while and finding time and energy to write just seemed an impossibility. Now that I feel I have some time to devote to developing with MonoTouch I hope to get some posts under way. This post shows how to load a view from a .xib file.

I had a need to create a view defined in a .xib but without a controller - it needed to be added as a subview to another view. When you add a new view to a project you get, just that, a view without a controller and no designer file either. When you add a view with a view controller, you do get a designer file and MonoDevelop will integrate with Xcode to let you add outlets and actions to the view. In this case, however, you can’t without just a little bit of setup on your part.

Having been away from MonoTouch for a while, I had to go looking for how to set up the view in order to be able to add outlets to it. I found a good answer here on stackoverflow (by Gunder). I’ll quickly work through the steps needed to be able to use your view.

Add a new iPhone or iPad View to the project. This will give you a .xib file, but no .cs or designer.cs file. You are free to edit this xib file in Xcode quite happily but Xcode won’t be able to get its Assistant Editor to show you a .h file in order to create outlets or actions in. Add a new class to the project. I call it the same as the xib file above, but that probably isn’t necessary. Change its base class to UIView (or UITableViewCell if that is required) and make the class partial. Decorate the class with [Register(“the_name_of_the_class”)] Build and then double click on the .xib file to design it in Xcode. You should now have a .h file that matches the name of the class that you added above. In Xcode, set the class of the view to your new class in the Identity Inspector. Note that the class name does not necessarily show up in the drop down list. You should now be able to add outlets and actions to the view. When you go back to MonoDevelop you should notice that it has created a designer.cs file and put your outlets and actions in it. That’s fantastic, now how to load it up and use the thing. This bit of code will do the trick

var nibObjects = NSBundle.MainBundle.LoadNib("YourViewName", theController, null);
var instantiatedView = (YourClassName)Runtime.GetNSObject(nibObjects.ValueAt(0));

From there onwards you use the view as you would use any other view.

On one of my first attempts, I wasn’t sure what to do with the result of nibObjects.ValueAt(). The result of the ValueAt call is an IntPtr, my naive guess of what to do with that was to call the constructor on UIView that takes an IntPtr. This is not recommended. This constructor is actually called during the call to LoadNib by the MonoTouch runtime - you do not need to call this yourself.

var instantiatedView = new YourClassName(nibObjects.ValueAt(0));

It turns out that this actually only “sort of works”, the view can be added to another view and used and at some point the outlets seem to be hooked up. I say at some point because what I noticed was that the button touch up action worked and I could update a label in the view quite happily. What I couldn’t do was update the label before that touch event.