Problems creating activity indicator for iOS data grid


Does anyone have a simple iOS Objective-C example of adding a UIActivityIndicatorView to the data grid component? I ran into an issue where I thought I could simply add the UIActivityIndicator view as a subview, but that failed.

My main view (self.view) contains a contentView (because I didn’t want to have the datagrid control going underneath the status bar for my sample app). In my viewDidLoad, I am adding the Data Grid subview to contentView, and then adding this contentView to the main self.view.

Any idea what I’m missing? Shouldn’t I be able to do [contentView addSubview:mySpinner] and have that appear over the top of my data grid?

Here are the relevant code snippets:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // Define our content view so that it doesn't extend into the status bar area
    _contentView = [[UIView alloc] initWithFrame:CGRectMake(0, kContentPadding, self.view.bounds.size.width, self.view.bounds.size.height-kContentPadding)];

    [self prepareSimpleShinobiDataGrid];

    [self doSomething];

- (void)prepareSimpleShinobiDataGrid{
    // Populate our array with sample data which INCLUDES HEADER ROW

    // Create our columns array using values passed in with the header row
    _columns = [[NSArray alloc] initWithArray:[[_rawData objectAtIndex:0] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\t"]]];

    // Create our data array using all elements of our original raw data EXCEPT THE HEADER ROW
    _data = [_rawData subarrayWithRange:NSMakeRange(1, _rawData.count-1)];
    _sortedData = [NSArray arrayWithArray:_data]; // Our sorted array
    // TODO: Add your Shinobi license key here
    [ShinobiGrids setLicenseKey:@"mylicensekey"];
    // Create a grid with 40 pixel padding
    _shinobiDataGrid = [[ShinobiDataGrid alloc] initWithFrame:CGRectInset(self.view.bounds, 10, 10)];

    // Define our columns
    //[self generateColumnsForShinobiDataGrid:_shinobiDataGrid];
    [_shinobiDataGrid addColumnsFromArray:[self generateColumnsForShinobiDataGrid]];
    // Set the grid data source
    _shinobiDataGrid.dataSource = self;
    _shinobiDataGrid.delegate = self;

    // Add to our view
    //[self.view addSubview:_shinobiDataGrid];
    [_contentView addSubview:_shinobiDataGrid];
    [self.view addSubview:_contentView];


/* The below code won't add a dummy view for some reason */
#pragma mark - SDataGridDelegate methods
- (void)shinobiDataGrid:(ShinobiDataGrid *)grid didChangeSortOrderForColumn:(SDataGridColumn *)column from:(SDataGridColumnSortOrder)oldSortOrder{
    NSLog(@"Sorting on [%@] - mode %u", column.title, column.sortOrder);
    // TODO: Wait for response from support to see why a subview cannot be added on top of the data grid
    UIView *someView = [[UIView alloc] initWithFrame:CGRectMake(-10, 30, 500, 500)];
    someView.backgroundColor = [UIColor blackColor];
    [_contentView addSubview:someView];
    NSLog(@"Where is this $#%@$ view?");
    if (column.sortOrder == SDataGridColumnSortOrderNone) {
        // No sorting; use the 'natural' order of the data
        self.sortedData = [NSArray arrayWithArray:_data];
    } else {
        // TODO: We are only sorting by string values for now. We may want to check specific column titles to sort numerically.
        self.sortedData = [_data sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2){
            // Column index that we'll need to reference in our new arrays
            NSUInteger index = [_columns indexOfObject:column.title];
            // We are receiving a tab separated string for comparison, so let's break it apart
            NSArray *itemDetail1 = [[NSArray alloc] initWithArray:[str1 componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\t"]]];
            NSArray *itemDetail2 = [[NSArray alloc] initWithArray:[str2 componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\t"]]];

            NSString *obj1 = itemDetail1[index];
            NSString *obj2 = itemDetail2[index];
            NSComparisonResult result = [obj1 localizedStandardCompare:obj2];
            return column.sortOrder == SDataGridColumnSortOrderAscending ? result : -result;
    // Stop spinning
    // TODO: Remove the ugly view once you can see it on top of the grid =)

    // Reload data for sorting to take effect (or not, if we're using natural order)
    [_shinobiDataGrid reload];


Greetings Program!

You need to add the view to the scrollview of the grid:


[_contentView addSubview:someView];


UIScrollView *scrollView = (UIScrollView *)[_contentView.subviews lastObject];
[scrollView addSubview:someView];

And if you ever need a progress indicator with a label, here’s a subclass of SEssentialsProgressIndicator that I put together:



Using the SortingTheGrid sample app, I did this:

@property(nonatomic, retain) UIActivityIndicatorView *activityIndicator;

- (void)shinobiDataGrid:(ShinobiDataGrid *)grid didChangeSortOrderForColumn:(SDataGridColumn *)column from:(SDataGridColumnSortOrder)oldSortOrder
    self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    self.activityIndicator.color = [UIColor redColor]; = CGPointMake(350, 400);

    UIScrollView *scrollView = (UIScrollView *)[_contentView.subviews lastObject];
    [scrollView addSubview:self.activityIndicator];
    [self.activityIndicator startAnimating];

    // Sort columns.	

    [self.activityIndicator stopAnimating];

    // Inform the grid that it should re-load the data
    [self.shinobiDataGrid reload];

I had to comment out the stopAnimating and make the indicator red because it was too quick in the sample app.

Hope that helps.