How to enter data in a 2-column grid layout


We’re redesigning a huge application at work and I’m tasked with figuring out whether the Shinobi grid is the appropriate tool for much of the data entry.

Our current data entry screens are nibs, and there are tons of them.

We’re looking to replace all these nibs with a more generic, simple, reusable type of layout.

Per the image…

(A) The field labels would be presented in the first column in the 2-column grid.  This you would just create in code, or perhaps read from an XML file.  

(B) This would be an array of values pulled from Core Data (which pulled them from Sqlite).  These need to go into the second column.

© The rows in the grid cannot be in any ol random order.  For example, the user is going to be irritated if they open the app the second time and see the rows listed as …

  • City
  • Last Name
  • State
  • First Name
  • Zip
  • Street

Current understanding / needs:

  1. I think sorting will be required here in order to enforce the order of the entry fields as shown in the first column of the grid, but that will mean attaching additional data to (A) that will allow the sorting to occur, but if I did have two data items in (A), a numeric sort order value, and a corresponding label value, I don’t know how I’d get the labels into the grid, while sorting with the numbers.

  2. The grid only has 1 property for it’s data.  There isn’t for example, a datasource for the labels column, and a datasource for the values column.  So I’m not sure how to set up the grid for this sort of data entry.

  3. The values in column 2 of the grid need to be aligned with their corresponding labels in column 1.  The user will be quite confused if they see “First Name” --> 98119.  I don’t know how to achieve that either.

Thanks for any help.


Greetings Program!

Not sure if this is the best way but it works and should give you a starting point.

// Address.h

#import <Foundation/Foundation.h>

@interface Address : NSObject {
    NSString *firstname;
    NSString *lastname;
    NSString *street;
    NSString *city;
    NSString *state;
    NSString *zip;

@property(nonatomic, copy) NSString *firstname, *lastname, *street, *city, *state, *zip;


// Address.m

#import "Address.h"

@implementation Address

@synthesize firstname, lastname, street, city, state, zip;


// ViewController.m

#import "ViewController.h"
#import "Address.h"

@interface ViewController ()

@property NSMutableArray *data;
@property NSArray *fieldLabels;


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [ShinobiDataGrids setLicenseKey:@"your license key"]; // TODO: add your trial license key here!
    // Create a grid - with a 40 pixel padding
    ShinobiDataGrid *shinobiDataGrid = [[ShinobiDataGrid alloc] initWithFrame:CGRectInset(self.view.bounds, 40,40)];
    // Add the field label column
    SDataGridColumn* labelColumn = [[SDataGridColumn alloc] initWithTitle:@"Label"];
    labelColumn.width = @150;
    [shinobiDataGrid addColumn:labelColumn];
    // Add the field value column
    SDataGridColumn* valueColumn = [[SDataGridColumn alloc] initWithTitle:@"Value"];
    valueColumn.width = @150;
    [shinobiDataGrid addColumn:valueColumn];
    // Mimic retrieving an address object from core data.
    Address *address = [[Address alloc] init];
    address.firstname = @"Tim";
    address.lastname = @"Smith";
    address.street = @"112 5th Ave"; = @"Seattle";
    address.state = @"WA"; = @"98119";
    // Set the field labels array in the order you want it to display.
    self.fieldLabels = @[@"First Name", @"Last Name", @"Street", @"City", @"State", @"Zip"];

    // Flatten the address object into an array in the same order. = [@[address.firstname, address.lastname, address.street,, address.state,]mutableCopy];
    // Set the data-source, this is the class responsible for supplying data to the grid.
    shinobiDataGrid.dataSource = self;
    [self.view addSubview:shinobiDataGrid];

#pragma mark - ShinobiDataGridDataSource methods

- (NSUInteger)shinobiDataGrid:(ShinobiDataGrid *)grid numberOfRowsInSection:(NSInteger)sectionIndex {

- (void)shinobiDataGrid:(ShinobiDataGrid *)grid prepareCellForDisplay:(SDataGridCell *)cell {
    // Both columns use a SDataGridTextCell, so we are safe to perform this cast
    SDataGridTextCell* textCell = (SDataGridTextCell*)cell;
    // Determine which column this cell belongs to.
    if ([cell.coordinate.column.title isEqualToString:@"Label"]) {
        textCell.textField.text = self.fieldLabels[cell.coordinate.row.rowIndex];
    else if ([cell.coordinate.column.title isEqualToString:@"Value"]) {
        textCell.textField.text =[cell.coordinate.row.rowIndex];




Wow, nice.  And quick response too.