views:

3882

answers:

6

How should I go about creating a UI similar to the Springboard (home screen) on the iPhone? I'd like a grid of evenly spaced buttons with images where I can respond to the button tap.

Is the UITable a good fit? Should I use a plain UIView and position the icons manually in DrawRect? Is there an alternative that will automatically evenly space the buttons, allow reorganization, and adjust the layout according to the iPhone orientation?

I come from a C#/Winforms background and am just now starting iPhone development on the Open Toolchain with 2.2.1 headers.

+1  A: 

You need to add your icons (which are UIViews of some sort) as subviews of your "Springboard" view. No custom drawing needed, and a UITable is thh absolute wrong way to go. You just need to do the math to place them correctly (by setting their frame).

August
Manual math route? I had hoped there was an easier way. Oh well. Thanks!I'm not smart about the UITable. Why is it not a good fit?
Nick VanderPyle
UITable is great for lists. Each object in its own row. A UIView, though, allows you to layout your own grid, with views wherever you want them.
August
Makes sense. From a .NET perspective, the UITable is more like a GridView than a TableLayout.
Nick VanderPyle
On the iPhone, a UITableView only has one column. Always. So it's ill suited to a grid. It's more of a fancy outlined list view.
Squeegy
+1  A: 

@August: I took your advice and added the UIButtons as subviews of the UIView rather than look further into the UITable. Thanks!

Hopefully the code below will help to jumpstart someone else. I've statically placed 4 buttons in a grid. It shouldn't be much harder to place any number of buttons according to the parent UIView's bounds and orientation.

@implementation IconView
- (id)initWithFrame:(struct CGRect)windowRect{
  self = [super initWithFrame: windowRect];
  if (self != nil){
    for(int i = 0; i < 4; i++){
      buttons[i] = [self buildButton];
      [self addSubview: buttons[i]];
    }
    [self reInit];
  }
  return self;
}
- (UIButton *) buildButton{
  UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
  [button setBackgroundImage: [[UIImage imageNamed:@"icon.png"] stretchableImageWithLeftCapWidth:60 topCapHeight:0] forState:UIControlStateNormal];
  return [button autorelease];
}
- (void)reInit{
  CGRect rect;
  rect = buttons[0].frame;
  rect.origin = CGPointMake(5, 5);
  buttons[0].frame = rect;

  rect = buttons[1].frame;
  rect.origin = CGPointMake(70, 5);
  buttons[1].frame = rect;

  rect = buttons[2].frame;
  rect.origin = CGPointMake(5, 70);
  buttons[2].frame = rect;

  rect = buttons[3].frame;
  rect.origin = CGPointMake(70, 70);
  buttons[3].frame = rect;
}
@end
Nick VanderPyle
What is "buttons"? How did you get a collection of UIButton's?
George
A UIButton is just a UIView with some extra methods. It would be trivial to change the example to use UIView instead of UIButton.
Kristopher Johnson
A: 

Use Arijasoft's gridView implementation. Its a static library that lets you generate the grid type of view with call backs and delegate methods for optimization

Nareshkumar
Is this a commercial library? If so, how much does it cost?
Tim Sullivan
The demo version uploaded on the site they say works till feb last day. contact them if you need the commercial library
Nareshkumar
+1  A: 

I've written some sample code to do something like this. See my Tiles blog entry, or just download the code: Tiles-v1.0.zip.

My code creates the icons as Core Animation layers, not as UIViews, but does demonstrate how to detect taps and allow reorganization of the icons. It doesn't handle orientation changes (yet).

Kristopher Johnson
+3  A: 

The Three20 library has a TTLauncherView class that provides this functionality. See http://three20.info/overview.

Kristopher Johnson
A: 

Old thread, but you should check out Alan Quartrmain's AQGridView too.

Joost Schuur