For a project that I am working on, I required a grid view and show some images in it. As this is something that is quite common, there are a lot of libraries out there. The one that I liked the most was AQGridView. It has a nice community, is open source and its developers contribute actively to the library. It is designed to be very similar to UITableView so you can get used to it in no time. Here’s a getting started post to create a grid view using interface builder for iOS.

The first step is getting AQGridView. You can get it from here. Its really simple to add it to your existing project. Just follow the instructions on the project page on github. If you are already familiar with working with other libraries with iOS, its really similar. Just drag and drop the AQGridView project in your project in XCode and add the dependencies in Target -> Project -> Build Settings and Target -> Project -> Build Phases.

We are going to need a controller for our grid view. Create a new subclass of UIViewController <AQGridViewDelegate, AQGridViewDataSource>. Let us name is MyGridViewController. We are implementing the AQGridViewDelegate and AQGridViewDataSource because we want this controller to be able to respond to AQGridView events and supply data to the AQGridView.

You then need to implement the following in your MyGridViewController.m

- (NSUInteger) numberOfItemsInGridView: (AQGridView *) aGridView // Returns the number of items in grid view.

- (AQGridViewCell *) gridView: (AQGridView *) aGridView cellForItemAtIndex: (NSUInteger) index  // returns a cell at given index

- (CGSize) portraitGridCellSizeForGridView: (AQGridView *) aGridView  // Returns the size of a cell in gridView

- (void) gridView:(AQGridView *)aqgridView didSelectItemAtIndex:(NSUInteger)index  // Called when a cell is selected

Let us first make the grid view in interface builder. Open the storyboard and create a new UIViewController and set its class as MyGridViewController. Then add a new UIView to the controller and set its class to AQGridView.

Then set the dataSource and delegate for the grid view also from the interface builder. Just hold Ctrl and drag from the dataSource (on the right tab) to your UIViewController in the storyboard and do the same for delegate.

You can also create an outlet into the MyGridViewController class by holding down Ctrl and dragging from the AQGridView that you created in the story board to MyGridViewController.h.

Now, we need to create our cells that we want to show in the grid. You can create custom cells by subclassing the AQGridViewCell. Create a new class MyGridViewCell and make it a subclass of AQGridViewCell. All you need in the class implementation is the method that creates the cell. The method can be very simple and can be customized as per your needs. Here’s a simple method to create a blank cell with a label.

#import "MyGridViewCell.h"

@implementation MyGridViewCell
- (id) initWithFrame: (CGRect) frame reuseIdentifier: (NSString *) aReuseIdentifier
    self = [super initWithFrame: frame reuseIdentifier: aReuseIdentifier];
    if ( self)
        // Create a label in the center of the frame
        UILabel *label = [[UILabel alloc] init];
        [label setCenter:CGPointMake((frame.origin.x+frame.size.width)/2, (frame.origin.y+frame.size.height)/2)];
        [label setText:@"Test Cell"];
        [self.contentView addSubview:label];

Now, in the MyGridViewController.m, you can implement the method that creates the cells. Keep in mind to use the cell identifier for reusing the cells. If you have worked with UITableView before, you should already be quite familiar with this. For newcomers, in short, this is something that would improve the performance quite a lot because it allows the cells to be reused in the grid view.

- (AQGridViewCell *) gridView: (AQGridView *) aGridView cellForItemAtIndex: (NSUInteger) index
    GridViewCell * cell = (GridViewCell *)[aGridView dequeueReusableCellWithIdentifier:@"MyCellIdentifier"];
    if ( cell == nil ) {
        cell = [[MyGridViewCell alloc] initWithFrame: CGRectMake(0.0, 0.0, cellWidth, cellHeight) reuseIdentifier: @"MyCellIdentifier"];
    return cell;