Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UItableView load data on scroll

In my app I am getting the data from the web-service and I have to display it in UITableView. But the condition here is I have to display only 10 records initially,then once the user scroll down I have to load more records.I tried searching it but didn't get any useful answer. I agree that I will use -

(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

to display the value,but how will I fetch only 10 records from the service and then other record based on scroll. Please provide some pointers or sample code.

Thanks

like image 371
Abhinandan Sahgal Avatar asked Feb 01 '12 07:02

Abhinandan Sahgal


4 Answers

In case if some one need it,i was able to solve my problem this way. First thing is you need the server configuration in such a way so that it should return 10 data at a time based on the row which is visible in TableView. This is the tableView delegate which get called and returns the visible cells in tableView

 -(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        int lastRow=[nameArray count]-1;
        if(([indexPath row] == lastRow)&&(lastRow<[categoryArray count]))  
        {

            if(tableView==m_pDetailsTableView)    {
                savedScrollPosition=lastRow;
                startCellValue=[NSString stringWithFormat:@"%d",0];
                endCellValue=[NSString stringWithFormat:@"%d",[nameArray count]+10];
                [self connectToServer]; //Method to request to server to get more data
            }
        }
    }

savedscrollPosition variable stores the variable as a point where you want to scroll the table view after load of data.

like image 112
Abhinandan Sahgal Avatar answered Nov 18 '22 16:11

Abhinandan Sahgal


Just insert the new data into your datasource see below

If you're using xml - check out XMLReader - turn XML into an NSDictionary this sample code below uses AFNetworking (which is non blocking) https://github.com/AFNetworking/AFNetworking/

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
        [self fetchMoreData];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self fetchMoreData];
}


- (void)fetchMoreData
{

    if ([resultArray count] > 0)
    {
       NSArray *visiblePaths = [myTableView indexPathsForVisibleRows];
       NSIndexPath *lastRow = [visiblePaths lastObject];

        // Check whether or not the very last row is visible.
        NSInteger numberOfSections = [myTableView numberOfSections];
        NSInteger lastRowSection = [lastRow section];
        NSInteger lastRowRow = [lastRow row];
        NSInteger numberOfRowsInSection = [myTableView numberOfRowsInSection:lastRowSection];

        if (lastRowSection == numberOfSections - 1 &&  
            lastRowRow== numberOfRowsInSection - 1) {

            DLog(@"it's the last row");
            if ([resultArray count]%10 == 0) { // use a divider based on your pagination
               [self fetchNextPage];
            }

        }
    }
}


-(void)getFeeds{
    ENTER_METHOD;

    [resultArray removeAllObjects];
    //reset this
   NSString *url = [NSString stringWithFormat:@"/webserviceurl.xml?offset=0"];
    [httpClient getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

        [self parseFeedsXMLString:operation.responseString];
        //  offset = offset + 10; // ONLY if there's results increment

    } failure:^(AFHTTPRequestOperation *operation, id responseObject){
        NSString *detailError=nil;
     }];

}

-(void)fetchNextPage{

    NSString *url = [NSString stringWithFormat:@"/webserviceurl.xml?offset=%d",offset];
    [httpClient getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {


        DLog(@"operation.responseString:%@",operation.responseString);
        [self parseNextFeedsXMLString:operation.responseString];
       // offset = offset + 10; // ONLY increment if there's results 


    } failure:^(AFHTTPRequestOperation *operation, id responseObject){

    }];

}



- (void)parseFeedsXMLString:(NSString *)xmlString
{

    NSError *parseError = nil;
    NSDictionary *xmlDictionary = [XMLReader dictionaryForXMLString:xmlString error:&parseError];
    DLog(@"xmlDictionary:%@",xmlDictionary);
    resultArray = [[NSMutableArray arrayWithArray:[[xmlDictionary objectForKey:@"feed"] objectForKey:@"entry"]]retain];

    [myTableView reloadData];
}

-(void)parseNextFeedsXMLString:(NSString *)xmlString
{

    NSError *parseError = nil;
    NSDictionary *xmlDictionary = [XMLReader dictionaryForXMLString:xmlString error:&parseError];
    DLog(@"xmlDictionary:%@",xmlDictionary);
    //[resultArray insertObject:e atIndex:[resultArray count]];

    NSMutableArray *results  = [NSMutableArray arrayWithArray:[[xmlDictionary objectForKey:@"feed"] objectForKey:@"entry"]];

    if ([results count]) {
        page++;
        for (NSDictionary  *dict in results) {
            [resultArray insertObject:dict atIndex:[results count]];
        }

    }
    [myTableView reloadData];
}
like image 32
johndpope Avatar answered Nov 18 '22 16:11

johndpope


You should read about lazy loading. The code is available at Apple's website. Download it here

http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html

check the code of

- (void)loadImagesForOnscreenRows 

method.

It uses the same approach you need. It gets the current scroll position of the table view and on the basis of that, it will get the cells displayed on the screen and their indexPath. On the basis of that you will be able to show those cells which are shown in the screen.

For showing 10 rows, a simple calculation is required.

like image 7
HarshIT Avatar answered Nov 18 '22 15:11

HarshIT


If I correctly understand your question ,you can do the following.

1 ) implement scrollViewDidScroll

2 ) check for visible rows in that

3 ) if you found the last row just call the web service for loading more data

4 ) on getting the data just reload the table

Try it .

like image 1
harshalb Avatar answered Nov 18 '22 16:11

harshalb