Apr 22

For a project I’m currently working on, I needed to show a ‘Load more’ cell when there were >25 results, this is not a basic 1-2-3 on how to fill tablecells with data, so below code is assuming you already have that and it’s left out

In my code I will fetch a maximum of 25 results (which can be less) and stick this into an array. If the array count is 25, we have to add an extra cell, to do this we increase the count by one:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        NSLog(@"Setting numberOfRowsInSection to %i",[self.localJsonArray count]);
        if ( [jsonArray count] < 25 ) {
                return [self.localJsonArray count];
        } else {
                return [self.localJsonArray count] + 1;
        }       
}

Next we populate the tablecells, we fill it with data from the index, and we look if we’re still working with data or are at the +1 we defined above:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CellIdentifier = @"Cell";
        ImageCell *cell = (ImageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (indexPath.row != [localJsonArray count] ) { // As long as we haven’t reached the +1 yet in the count, we populate the cell like normal
                if (cell == nil) {
                        cell = [[[ImageCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
                }
                NSDictionary *itemAtIndex = (NSDictionary *)[self.localJsonArray objectAtIndex:indexPath.row];
                [cell setData:itemAtIndex];
        } // Ok, all done for filling the normal cells, next we probaply reach the +1 index, which doesn’t contain anything yet
        if ( [jsonArray count] == 25 ) { // Only call this if the array count is 25
                if(indexPath.row == [localJsonArray count] ) { // Here we check if we reached the end of the index, so the +1 row
                        if (cell == nil) {
                                cell = [[[ImageCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
                        }
                        // Reset previous content of the cell, I have these defined in a UITableCell subclass, change them where needed
                        cell.cellBackground.image = nil;
                        cell.titleLabel.text = nil;
                        // Here we create the ‘Load more’ cell
                        loadMore =[[UILabel alloc]initWithFrame: CGRectMake(0,0,362,73)];
                        loadMore.textColor = [UIColor blackColor];
                        loadMore.highlightedTextColor = [UIColor darkGrayColor];
                        loadMore.backgroundColor = [UIColor clearColor];
                        loadMore.font=[UIFont fontWithName:@"Verdana" size:20];
                        loadMore.textAlignment=UITextAlignmentCenter;
                        loadMore.font=[UIFont boldSystemFontOfSize:20];
                        loadMore.text=@"Load More..";
                        [cell addSubview:loadMore];
                }
        }
        return cell;
}

And voila, cell #26 is the ‘Load more’ cell, next we start detecting if it’s that cell that’s being selected:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        if ( [jsonArray count] == 25 ) { //  Only call the function if we have 25 results in the array
                if (indexPath.row == [localJsonArray count] ) {
                        NSLog(@"Load More requested"); // Add a function here to add more data to your array and reload the content
                } else {
                       NSLog(@"Normal cell selected"); // Add here your normal didSelectRowAtIndexPath code
               }
        } else {
                       NSLog(@"Normal cell selected with < 25 results"); //  Add here your normal didSelectRowAtIndexPath code
        }
}
 

Note that I’m working with 2 arrays here, jsonArray and localJsonArray, the jsonArray is what I fill with new results, i.e. 1-25 26-50, the localJsonArray is what’s being filled more and more, so on every ‘Load More’ selection, the localJsonArray will grow with +25 if there’s >= 25 items to load.

8 Responses to “Adding a ‘Load more’ cell in your UITableView”

  1. Cody says:

    Hello,

    First off, finding anything on this subject is extremely hard! Secondly your tutorial helped a little but im new to Objective-C so when it comes to custom UITableCell’s im a little lost.

    You used an object of ImageCell. I’m not sure what this is or where it came from. Would it be possible to post the source for this tutorial? Thanks.

  2. Jeroen says:

    ImageCell is the name of a seperately included file: ImageCell.h

    Basically it’s something like:
    —–
    // ImageCell.h
    #import

    @interface ImageCell : UITableViewCell {
    // put some interface things here like an image, a label, etc..
    }

    —-
    // ImageCell.m
    #import “ImageCell.h”

    @implementation ImageCell

    - (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
    }

    - (void)layoutSubviews {
    [super layoutSubviews];
    // getting the cell size
    CGRect contentRect = self.contentView.bounds;
    // some stuff here to setup labels and images
    }

    - (void)dealloc {
    }

    @end
    —-

    Then do a #import ImageCell.h in the ViewController .m file that has the table in it, and voila, the ImageCell as in the code of the tutorial. (very plain, but you can dress it from there)

    There’s a full tutorial at: http://iphone.zcentric.com/2008/08/05/custom-uitableviewcell/ if you want it more specific

  3. Cody says:

    Got it working, thanks for the info! Great help

  4. Pritish says:

    I got an app crash on these two lines:

    From my Table view

    NSDictionary *itemAtIndex = (NSDictionary *)[self.arrayProperty_Name objectAtIndex:indexPath.row];
    [cell setData:itemAtIndex];

    From ImageCell.m

    self.titleLabel.text = [dict objectForKey:@"title"];

  5. Jeroen says:

    What’s the crash error from the debug window ?

  6. Rita says:

    thanks! and this is great… but could you explain how to setup and fill the local json array with the jsonArray? and how do execute new request to the server with new results?

    thanks in advance

  7. Jeroen says:

    Hi Rita,

    You can fill the array with:

    if (self.localJsonArray == nil) {
    self.localJsonArray = [[NSMutableArray alloc]init]; // init the local array if it’s empty
    }
    [self.localJsonArray addObjectsFromArray:self.jsonArray];

    And you can detect the ‘load more’ click with something like this in the didSelectRowAtIndexPath function:

    if ( [jsonArray count] == 25 ) { { // only check for the load more function if we have 25 results in the dynamic array
    if (indexPath.row == [localJsonArray count] ) { // See if we reached the +1 in the results
    [self laadJSONTabel]; // function to load more results
    [populairTable reloadData]; // reload the table
    } else {
    // your normal didSelectRowAtIndexPath function here
    }

    Since we did a +1 on the numberOfRowsInSection in the initial example, we detect if we reached that +1 in above example and call ‘laadJSONTabel’ to load more results from wherever you’re getting your JSON from

  8. Andy says:

    Great post! Definitely in my bookmarks now.

Leave a Reply

preload preload preload