views:

64

answers:

2

Hi,

My app requires an interface that has many buttons, text fields and matrixes. And they need to change from time to time. Right now I do this by having all elements in IB already and hiding/showing/moving them when needed. What would others recommend? Should I do that? Should I use an NSTabView? NSView? Should create the elements programatically? If so, what if I have an element that is already created that I need again without changes? It would be a waste of releasing it and creating it again.

Any help would be greatly appreciated.

+1  A: 

Your current approach sounds fine. If you're showing/hiding them but otherwise they remain unchanged, why go through the trouble of creating them with code, when your XIB keeps a "freeze-dried" copy of exactly what you need already?

As long as you're keeping them within logical groups, you can just move/swap/show/hide the group's container (like NSBox or an NSView). If you have a LOT of logical groups, which aren't always shown every session, you can separate them out into their own XIBs and only load them when they're needed, to save launch time and memory.

If you use NSViewController, it's even better because you can make clean breaks for each logical group. Load the panel as the view and the view controller will keep outlets/actions and has a one-to-one relationship with a xib.

Joshua Nozzi
I have a lot of logical groups (~ 30). Right now my groups share the same button that's been in IB from the start but they change it if needed. I do this without any views, just a bunch of elements on my window. But if I had all those views then maybe it's better to create/remove them programatically? Because the views can't share the same button... I don't know much about NSViewController so I don't really know what it's capable of. I'll have to educate myself about it in the future.
+2  A: 

In my opinion, it's better to create interfaces programmatically if you have to animate views around a lot. If it's just a matter of hiding/unhiding them, IB works great, but if you need re-layout or create unknown numbers of views dynamically it's not worth trying to make it all work with nib files.

As for general advice:

  • Create subclasses (from UIView or UIControl or one of their subclasses) for every kind of element you're going to use. It's tempting to piece together composite views from your UIViewController, but you'll really be much better off creating real classes.

  • Study the standard Cocoa view classes, and try to create similar API:s in your own controls and views.

  • Put as much data (sub-element positioning etc) into a plist, so that you can easily change it from one centralized place instead of having to dig around in the code.

If you are often creating several dozen short-lived views, it's worth keeping them in a pool and reusing them. But if it's just a few labels being added and removed intermittently I wouldn't worry too much about it. As usual: don't optimize too early.

Felixyz
The OP stated "It would be a waste of releasing it and creating it again." It seems to me a much bigger waste to load all variations up front and keep them in memory in case they are needed, than to create the ones you need when you need them.
mbmcavoy
@mbmcavoy Sometimes it is a waste, sometimes (usually) it's not. In any case, one wouldn't "load all variations up front". Instead you add objects to the pool *if and when you create them* and mark them as unused when you remove them from the interface. (Or only move them to the pool when you remove them.) You could even flush the pool if you notice that most of the objects haven't been used in a long time (but in that case you probably didn't need the pool in the first place).
Felixyz
@Felixyz "But if it's just a few labels being added and removed intermittently I wouldn't worry too much about it." Sorry for my misunderstanding here but do you mean that I should just deallocate them or reuse them? (in the case of just changing minor things)
Hard to say without knowing more about your scenario. If it's basically the same set of controls/views which just need to be adjusted from time to time, it's probably best to keep them around, maybe in a fixed structure (rather than a pool). But if the interface is more fluid, with new constellations of elements being generated, you should just release and forget the views, and create new ones later, *unless* this becomes a real performance bottleneck, in which case you should use a pool.
Felixyz
There are about 30 variations of things changing.. Sometimes just a title, sometimes the frame, sometimes removing an element.. I'm not sure deallocating and creating again should be a big problem.. (I haven't done any real tests to see the speed by which it happens).