Quick Start Guide – Objective C

Introduction

The following guide will get you up-and-running with the ShinobiDataGrid as quickly as possible. In this guide we’ll cover initial project set-up, how to specify a datasource and some simple styling. The end result will be a grid that displays a list of people as shown below. You can follow along with the related code sample: GettingStarted.xcodeproj.

GettingStartedGrid

 

Installation

ShinobiGrids now ships with an installer, to make it easier to get started. To find the installer open the ‘ShinobiGrids.dmg’ file which you downloaded from ShinobiControls and look for ‘install.pkg’.

To install the ShinobiGrids framework and documentation run the ‘install.pkg’ file. This will install the framework and documentation into Xcode for you. This means you can add the framework to your project in the same way as you would any of the frameworks which are automatically shipped with Xcode.

If you don’t want to run the installer, the framework is also contained within the ‘ShinobiGrids’ folder in the disk image. Regardless of whether you ran the installer, you should copy this folder onto your machine. Drag the ‘ShinobiGrids’ folder onto the Desktop icon in the disk image. This will copy the folder onto your desktop.

The ‘ShinobiGrids’ folder contains:

  • A copy of the framework.
  • A copy of the documentation for the framework.
  • A set of samples to demonstrate getting started with ShinobiGrids.
  • An uninstall script for uninstalling the ShinobiGrids framework and documentation from Xcode.
  • The Xamarin.ios version of the framework.
  • A README file with setup steps.
  • A change log stating the changes made in each release.
  • A copy of the ShinobiGrids Licence.
  • A text file containing the version number of the framework.

Creating the basic grid

Start-up Xcode and create a new project via File / New / Single View Application.

Within your newly created project add a reference to the ShinobiGrids framework. The easiest way to do this is to locate the folder where you installed the framework, locate the ShinobiGrid.framework and drag it directly into your project.

ShinobiGrids makes use of a few other frameworks, so add the following as well: – QuartzCore framework – Security.framework (Trial version only)

Open up ViewController.h and import the ShinobiGrids.h file:

#import <ShinobiGrids/ShinobiGrids.h>

@interface ViewController : UIViewController 

@end

Next open up ViewController.m and add the following code:

@implementation ViewController
{
    ShinobiDataGrid* _shinobiDataGrid;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [ShinobiGrids setLicenseKey:@"your license key"]; // TODO: add your trial licence key here!

    // create a grid - with a 40 point padding
    _shinobiDataGrid = [[ShinobiDataGrid alloc] initWithFrame:CGRectInset(self.view.bounds, 40,40)];

    // add to the view
    [self.view addSubview:_shinobiDataGrid];
}

In the above code, within the viewDidLoad method, an instance of a ShinobiDataGrid is created and assigned to the _shinobiDataGrid ivar (instance variable). The frame of the data-grid is inset a few points within the view bounds, which means it will occupy the entire view, with a small margin. Finally, the data-grid is added as a sub-view of the view controller.

If you have downloaded a trial version of the ShinobiGrids you will have been issued with a trial license key. Add the key that you were supplied with at the location indicated above.

Creating some data

The next step is to create some data for the grid to render. Typically this data will be a collection of ‘data objects’ that are used within your application, this could be a collection of emails, contacts, flight details … all sorts of things!

For the purposes of this quick-start guide we’ll create some dummy data.

Control-click the project and select the New File … option, selecting the iOSCocoa TouchObjective-C class template. Name the class PersonDataObject and make it a subclass of NSObject.

Open up the newly created PersonDataObject.h file and add the following:

@interface PersonDataObject : NSObject

@property (retain, nonatomic) NSString* name;
@property (retain, nonatomic) NSNumber* age;

+ (PersonDataObject*) personWithName:(NSString*)name age:(NSNumber*)age;

@end

This defines name and age properties together with a ‘factory’ method that makes it easier to create instances of this class. Open up PersonDataObject.m and add the following:

@implementation PersonDataObject

+ (PersonDataObject*) personWithName:(NSString *)name age:(NSNumber *)age
{
    PersonDataObject* obj = [[PersonDataObject alloc] init];
    obj.name = name;
    obj.age = age;
    return obj;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"%@ - %@", _name, _age];
}

@end

We are letting Xcode synthesize the two properties automatically. The implementation of the descriptionmethod is just for convenience, it outputs the person’s name and age when an object is logged or printed in the output window.

Now that we have a suitable object, open up ViewController.m and import the header:

#import "PersonDataObject.h"

Then add an NSArray instance variable and a utility method to create the test data:

@implementation ViewController
{
   ShinobiDataGrid* _shinobiDataGrid;
    NSArray* _data;
}

- (void)createSomeTestData
{
    // create some data to populate the grid
    _data = @[[PersonDataObject personWithName:@"Leonardo" age:@45],
    [PersonDataObject personWithName:@"Michelangelo" age:@42],
    [PersonDataObject personWithName:@"Donatello" age:@47],
    [PersonDataObject personWithName:@"Raphael" age:@36]];
}

For the sake of brevity, the imaginatively named createSomeTestData method creates just 4 people. Within a real application you will probably have tens, hundreds or even thousands of items rendered within your grid.

Now that we have some data, it’s time to prepare the data-grid to display it …

Creating some columns

Before informing the data-grid of the data objects that are being rendering, you need to tell the grid how to render this data. The data-grid is composed of rows which run vertically and columns which run horizontally. Typically each column will represent a property of the data object being rendered within the grid.

The PersonDataObject has two properties, age and name, so we’ll go ahead and add a column for each property.

Open up ViewController.m and at the end of the viewDidLoad method add a couple of columns:

// add a name column
SDataGridColumn* nameColumn = [[SDataGridColumn alloc] initWithTitle:@"Name"];
nameColumn.width = @484;
[_shinobiDataGrid addColumn:nameColumn];

// add an age column
SDataGridColumn* ageColumn = [[SDataGridColumn alloc] initWithTitle:@"Age"];
ageColumn.width = @200;
[_shinobiDataGrid addColumn:ageColumn];

The above code adds two columns to the grid, one for rendering the person’s age and the other for their name.

The data-grid uses a concept called virtualization for rendering the data objects. In order to minimize memory usage, the grid only creates cells for the rows which are currently visible. As the user scrolls the grid, the cells which move out of view are re-cycled, i.e. they are re-used for the rows that have now become visible.

This re-cycling of cells all happens automatically. All you have to do is specify the ‘type’ of cell that you would like the data-grid to create for cells in each column.

Within this example the person’s name and age are going to be rendered as ‘text’ , which is why an SDataGridTextCell is used.

The columns are a very important component of the data-grid, as well as being used to specify cell types, you can also specify the sort behaviour, styles, width and all kinds of other properties.

Now that the data-grid is fully configured it is time to add the data …

Adding a Datasource

In order to render your data within the data-grid you need to supply a ‘datasource’, this is a class that adopts the SDataGridDataSource protocol methods.

ShinobiTipUITableView

 

Open up ViewController.h and adopt the SDataGridDataSource protocol:

@interface ViewController : UIViewController SDataGridDataSource

You can use any class you like as the datasource, however, here we are just using the view controller for simplicity.

The SDataGridDataSource protocol defines two mandatory methods that must be implemented. We’ll go ahead and add them now. Open up ViewController.m and add the following:

-(NSUInteger)shinobiDataGrid:(ShinobiDataGrid *)grid numberOfRowsInSection:(NSInteger) sectionIndex
{
    return _data.count;
}

This method informs the grid of the number of rows in each section. The data-grid allows you to group items within sections, for example, you might want to group a large list of people objects by the first letter of their name. In this example, we have a ‘flat’ list without sections, so the above code simply returns the number of items in the array. Next add the following:

- (void)shinobiDataGrid:(ShinobiDataGrid *)grid prepareCellForDisplay:(SDataGridCell *)cell
{
    // both columns use a SDataGridTextCell, so we are safe to perform this cast
    SDataGridTextCell* textCell = (SDataGridTextCell*)cell;

    // locate the person that is rendered on this row
    PersonDataObject* person = _data[cell.coordinate.row.rowIndex];

    // determine which column this cell belongs to
    if ([cell.coordinate.column.title isEqualToString:@"Name"])
    {
        // render the name in the 'name' column
        textCell.textField.text = person.name;
    }
    if ([cell.coordinate.column.title isEqualToString:@"Age"])
    {
        // render the age in the 'age' column
        textCell.textField.text = [person.age stringValue];
    }
}

As mentioned in the previous steps, each grid declares the type of cell that the grid should create for the cells within the column. The data-grid creates the required cells then invokes the above method on the datasource so that it can prepare the cell for display.

The cell has a coordinate property which indicates its location within the grid. The above code uses the coordinate.row.rowIndex to locate the data object that this row represents. Following that, the coordinate.column.title is used to identify the column for this cell, and the name or age property value used accordingly.

ShinobiTipDetectingColumns

 

With these two methods in place, the final step is to set the data-grid datasource. At the end of viewDidLoad add the following:

_shinobiDataGrid.dataSource = self;

If you build and run, you now have a fully functioning data-grid:

GettingStartedGrid

 

If you got stuck at any point, take a look at our related code sample: GettingStarted.xcodeproj

Now that you have created a basic data-grid sample, why not read about selection or sorting? There is a whole lot more you can do with your data now that it is in a data-grid!