Berichten met label NIB
Building iPhone applications using MonoTouch, howto: using a view without a controller
Geplaatst door Richard de Zwart in .NET, mobility, technical op 25 januari 2010
Of course, a view without a controller is not very useful in itself, but in this post I want to show you how I solved a small re-usability problem.
I’m working on a small open-source project on Codeplex that aims to build a player for the Hanselminutes podcasts. It is nothing very special, but it gives me a nice playground to find out new stuff.
So there is a “Loading playlist” message and a “Buffering audio” message displayed at the appropriate moments. You can do that in a lot of ways, but in this application, a semi-transparent view was chosen that is overlaying the current view. It has a text (of course) and a UIActivityIndicatorView (who comes up with these names????).
I try to follow three rules when building the UI:
- All the UI is done with the Interface Builder. That allows me to leave the actual design to someone who knows designing.
- Every view is in a separate NIB. That way not all the UI has to be loaded at startup, which improves user-perceived performance
- Loosely couple the view, to make reuse easier. That means a simple interface (as in ‘programming interface’) to the rest of the world, and all the view-related code inside the NIB
In this case I want a view that can be called from different controllers (re-usability), so when I add a file to my MonoDevelop project I choose “View Interface Definition”:
It’s no so different form what you do (at least, what I do) most of the time when you choose View Interface Definition with Controller. You add your UI-elements, define some outlets, but then you want to activate this view from some controller, any controller.
What I came up with, is the following.
public class UIHelper { UIViewController _controller; BusyView _busyView; public UIHelper (UIViewController controller) { _controller = controller; NSArray views = NSBundle.MainBundle.LoadNib("BusyView", _controller, null); _busyView = new BusyView(views.ValueAt(0)); _controller.View.AddSubview(views); _controller.View.SendSubviewToBack(_busyView); } }
It is a helper class that loads the view at construction time. It gets passed in the controller that will display the view. Then I load the NIB where the view is in. This gives me back an array. Of what? Well as the documentation says:
An array containing the top-level objects in the nib file. The array does not contain references to the File’s Owner or any proxy objects; it contains only those objects that were instantiated when the nib file was unarchived. You should retain either the returned array or the objects it contains manually to prevent the nib file objects from being released prematurely.
So you get the top-elements (actually: the IntPtr’s of them) from the NIB. In a file with only one view the first one is probably (…fingers crossed) the right one.
I add the view to the SubViews of the controller and make sure it does not show before it was meant to.
Showing the view
Whenever I need the view to display I call:
_busyView.Show(message); _controller.View.BringSubviewToFront(_busyView);
The first line calls a method on the partial class in the NIB to set the text of a label. The second line makes the view visible.
What’s not to like about this solution
Well, the magical string with the name of the NIB, “BusyView”. And the magical number 0 the denotes the right object in the list of objects in the NIB.
Any ideas for improvement? Please react!

