UITableView滚动时加载数据

11

我正在开发的应用从Web服务获取数据,我需要在UITableView中显示它。 但是条件是我只能最初显示10条记录,然后当用户向下滚动时,我必须加载更多的记录。我尝试搜索,但没有找到有用的答案。 我同意使用 -

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

如何显示值,但我该如何从服务中获取仅10条记录,然后基于滚动获取其他记录。请提供一些指针或示例代码。

谢谢


尝试一下lazyLoading的概念怎么样? - Aravindhan
不,我不想实现延迟加载,我希望每次加载10条记录。 - Abhinandan Sahgal
6个回答

11

如果有人需要,我用以下方式解决了我的问题。 首先,你需要将服务器配置成这样,以便根据TableView中可见的行每次返回10个数据。 这是调用并返回tableView中可见单元格的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变量存储了一个点,你想在数据加载后滚动表格视图到这个点。


7

您应该了解懒加载。代码在苹果的网站上可用。在这里下载:

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

检查代码。

- (void)loadImagesForOnscreenRows 

方法。

它使用与您所需相同的方法。它获取表视图的当前滚动位置,并根据此获取在屏幕上显示的单元格及其indexPath。基于此,您将能够显示在屏幕上显示的单元格。

显示10行需要进行简单的计算。


1
是的,我同意,我可以应用逻辑来显示它,但是为此我也必须一次性从 Web 服务加载整个数据。我想从服务中获取10条记录并显示。 - Abhinandan Sahgal
不,不是整个数据,而只是屏幕上显示的单元格所属的数据。因此,在查看表时首先加载您要求的10条记录。之后,仅获取那些屏幕上显示的单元格所对应的记录。惰性加载意味着仅加载所需的信息,而不是整个数据。 - HarshIT
如果您能加入“iPhone”聊天室,我们可以详细讨论。我很乐意帮助您。 - HarshIT

4

只需将新数据插入到您的数据源中,如下所示

如果您正在使用XML,请查看XMLReader - 将XML转换为NSDictionary。此示例代码使用AFNetworking(非阻塞)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];
}

1
如果我正确理解了你的问题,你可以按照以下步骤操作:

1)实现scrollViewDidScroll方法

2)检查其中可见的行

3)如果找到了最后一行,就调用网络服务来加载更多数据

4)在获取数据后,重新加载表格

试试看吧。

0
 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger lastSectionIndex = [tableView numberOfSections] - 1;
NSInteger lastRowIndex = [tableView numberOfRowsInSection:lastSectionIndex] - 1;
if ((indexPath.section == lastSectionIndex) && (indexPath.row == lastRowIndex)) {
    i = i +10;
    NSString *unescaped = mySearchBar.text;
    NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
    [PServiceAPI searchKeyWord:escapedString withOffSet:i Handler:^(NSArray *results, NSError *error) {
        if (error == nil) {
            [arBase addObjectsFromArray:results];
            [myTableView2 reloadData];

        }
    }];

  }
}

0
您可以调整tableView:numberOfRowsInSection:方法的返回值,每当您想插入十行时,可以将其加上10作为返回值。
抱歉我的英语不好。

但是我仍然需要一次性将整个数据加载到数组中。对吧?但是我想要获取10条记录并显示。 - Abhinandan Sahgal
我认为这个问题很普遍;你可以一次请求大量记录(超过10条);但是你可以通过调整numberOf***来控制tableView中的单元格数量,当你滚动到底部时,可以再插入10个单元格,如果记录不在本地,则需要向Web服务器请求新的记录。 - yebw
没错,Yebw。我想再发一个请求到Web服务器上以获取另外10条记录。有什么办法只获取10条记录吗? - Abhinandan Sahgal
你的通信协议必须支持,我认为。 - yebw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接