views:

505

answers:

4

What is the best approach to implement tabs that look like web applications on the iPhone, like the screenshot below (notice the "Checkin-Info-Friends" tabs)? These are not part of the UIKit standard library, but seems to be very common lately.

I've spent considerable time developing applications for the iPhone, but not developing controls like that one. What would be the best approach here:

  • create a new UIView for each tab content, and add the three subviews to the mainview straight away?
  • create new UIViews only when the user clicks on each of the tabs?
  • Put all the content in a UIScrollView, and just change the page as the user clicks on each tab?

Maybe there are open source controls for this out there? I couldn't find anything.

alt text

+1  A: 

My approach to a similar problem was to make all 4 (in my case) tab views, but respond to didReceiveMemoryWarning by releasing all but the current tab view. (Then, of course, you must make sure that you create the new view, if it doesn't exist, when the user chooses a new tab.)

I thought this was a good compromise - a speedy reaction to the user at first (and in my case memory footprint is at its lowest at this point in my app), and then a response to low memory to avoid being shot.

Jane Sales
So you would have one tabviewcontroller, but 4 views, each one including the "think coffee" and the tabs (from the picture above)?
Eduardo Scoz
In your case, I'd have 1 tabview controller, one base view with the "think coffee" and then 3 smaller tab views for the lower portion of the screen, one for each tab. (Memory saving if the tab views aren't full screen.)
Jane Sales
(Though this decision for me was simple, because each of my tabviews just has some buttons - so it's simple to use the same view controller for all the tab views - the logic is just simple button action methods.)
Jane Sales
Thanks, Jane. I'm doing something like that after all. It seems it'll work.Any idea on how I could skin buttons or a UISegmentedControl to make it look like the tabs above?
Eduardo Scoz
+1  A: 

I think it best just to have three UIView* references to the subviews in the parent view or view controller, all initially null, then to have subroutine to hide the other two views if they are visible and either construct and show or just show the new view. Assuming no extraordinary memory requirements.

I think with such a small screen area load/unload concerns at the subview level are unlikely to be a concern, but if the parent views need to be loaded/unloaded, the subviews should all go (be both hidden and unloaded), and on reload, loadView should call the routine described in the last paragraph at startup.

If there is in fact a great deal of memory or resource use by any of the three subviews, then my advice is reversed and each of the subviews and/or any memory-intensive objects behind them should be not only hidden but unloaded whenever possible. I think with your use of Google maps there, a need to unload when hidden might apply to that.

Is this th right point to make? Is there some extra detail I'm missing?

martinr
+1  A: 

You can have each tab be a real view controller with nib and everything. The only catch is that you must forward on the standard view controller calls you want to receive (viewWillAppear, etc) but it makes the coding much cleaner since you code just as you would for any other view (although for a smaller space).

You call each controllers "view" property to get out the view, which you add as a subview of a container view you have under the tabs.

Kendall Helmstetter Gelner
+1  A: 

If all three are table views, you might get away with using a single UITableViewController that changes contents based on the selected tab. Otherwise I second KHG's comment of using real view controllers to back up each of the subviews.

For the tabs themselves consider subclassing UISegmentedControl.

Frank Schmitt
Thanks for the answer, Frank. Not all the views are tables, I should have mentioned that.Great idea on the UISegmentedControl.
Eduardo Scoz
Hi Frank, I couldn't figure out how to subclass UISegmentedControl and replace the drawing method, to output my own images.. Would you have any idea which method I should override?
Eduardo Scoz
I don't have a lot of (well, any) experience subclassing UI elements. You could override the `drawRect` method, use `[super widthForSegmentAtIndex]` to grab the widths and `[super selectedSegmentIndex]` to find out which one to highlight. You could also walk the subview tree and tell any UILabels to draw themselves. But I'm not sure how far you can go before you're in undocumented API rejection territory.
Frank Schmitt
Thanks for the tips, Frank!
Eduardo Scoz