How to load my tableview with a pagination?

12,022

UITableView can support skimming through many rows of data, however fetching large amounts of remote data can slow down your app, use up too much memory, and bog down your web server. This is all wasteful if users aren't ever going to scroll down that far. In this episode you'll learn how to perform automatic UITableView paging using an easy technique.

Initialization

- (void)viewDidLoad {
    [super viewDidLoad];

    self.beers = [NSMutableArray array];
    _currentPage = 0;
}

Issue HTTP Request for the current page

- (void)fetchBeers {
    NSString *urlString = [NSString 
      stringWithFormat:@"http://localhost:3000/beers.json?page=%d", 
      _currentPage];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFJSONRequestOperation *operation = 
      [[AFJSONRequestOperation alloc] initWithRequest:request];
    [operation setCompletionBlockWithSuccess:
      ^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"responseObject %@", responseObject);

        _totalPages = [[responseObject 
          objectForKey:@"total_pages"] intValue];

        for (id beerDictionary in [responseObject 
                                    objectForKey:@"beers"]) {
            Beer *beer = [[Beer alloc] 
              initWithDictionary:beerDictionary];
            if (![self.beers containsObject:beer]) {
                [self.beers addObject:beer];
            }

            [beer release];
        }

        [self.tableView reloadData];

    } failure:
      ^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", [error localizedDescription]);
        [[[[UIAlertView alloc] 
          initWithTitle:@"Error fetching beers!"
                message:@"Please try again later"
               delegate:nil
          cancelButtonTitle:@"OK"
          otherButtonTitles:nil] autorelease] show];
    }];

    [operation start];
    [operation release];
}

Offset number of rows

- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section {
    if (_currentPage == 0) {
        return 1;
    }

    if (_currentPage < _totalPages) {
        return self.beers.count + 1;
    }
    return self.beers.count;
}

Render the cells

- (UITableViewCell *)beerCellForIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"cell";
    UITableViewCell *cell = [self.tableView 
dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[[UITableViewCell alloc] 
            initWithStyle:UITableViewCellStyleSubtitle
          reuseIdentifier:cellIdentifier] autorelease];
    }

    Beer *beer = [self.beers objectAtIndex:indexPath.row];
    cell.textLabel.text = beer.name;
    cell.detailTextLabel.text = beer.brewery;

    return cell;
}

- (UITableViewCell *)loadingCell {
    UITableViewCell *cell = [[[UITableViewCell alloc] 
                 initWithStyle:UITableViewCellStyleDefault
               reuseIdentifier:nil] autorelease];

    UIActivityIndicatorView *activityIndicator = 
      [[UIActivityIndicatorView alloc] 
      initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    activityIndicator.center = cell.center;
    [cell addSubview:activityIndicator];
    [activityIndicator release];

    [activityIndicator startAnimating];

    cell.tag = kLoadingCellTag;

    return cell;
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row < self.beers.count) {
        return [self beerCellForIndexPath:indexPath];
    } else {
        return [self loadingCell];
    }
}

Fetching the next page

- (void)tableView:(UITableView *)tableView 
  willDisplayCell:(UITableViewCell *)cell 
forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (cell.tag == kLoadingCellTag) {
        _currentPage++;
        [self fetchBeers];
    }
}

This example is from NSScreencast Episode 8 - Automatic UITableViewPaging.

Share:
12,022
hacker
Author by

hacker

Updated on June 08, 2022

Comments

  • hacker
    hacker almost 2 years

    I have a tableview in my application, into which I am loading different types of cells. This is fine and working well. But now I need to do the pagination. I need to pass the page number to the service as one, two etc and to load that when the 1st page ends. For the first one I am loading the count is 5, after that when scroll ends I need to load the next. I am new to this pagination. Can anybody gave me the direction to follow?I tried like this But it will become an infinite loop `

    -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *) cell     forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        int count1 = [array count];
        NSLog(@"%d",count1);
         NSLog(@"%d",indexPath.section);
        NSLog(@"%d",max);
        NSLog(@"%d",min);
    
        if(indexPath.section == count1 - 1) // If going to display last row available in your source
        {
    
            NSLog(@"%d",max);
              NSLog(@"%d",min);
    
    
            if(min <= max) 
            {
    
    
    
                [self getmessages:min];
            }
            else
            {
                self.mtableview.tableFooterView = nil; //You can add an activity indicator in tableview's footer in viewDidLoad to show a loading status to user.
            }
    
        }
    }
    

    `

  • onmyway133
    onmyway133 over 10 years
    @laxonine is this from nsscreencast.com/episodes/8-automatic-uitableview-paging ? If yes, please give the link under your post