UITableView Pagination - Bottom Refresh to Load Ne

2019-01-25 08:11发布

I am trying to implement loading data from my backend with pagination. I have seen this, but it loads all the data, all then time. Is this the right way or am I doing something wrong?

Thanks in advance.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell

    print(indexPath.row)

    if (indexPath.row + 1 < self.TotalRowsWithPages) {
        cell.textLabel?.text = "\(self.myarray!.[indexPath.row].body)"
    } else {

        cell.textLabel?.text = "Loading more data...";

        // User has scrolled to the bottom of the list of available data so simulate loading some more if we aren't already
        if (!self.isLoading) {
            self.isLoading = true;
            self.TotalRowsWithPages = self.TotalRowsWithPages + self.PageSize
            self.getmoredata()
        }
    }

    return cell
}

3条回答
成全新的幸福
2楼-- · 2019-01-25 08:26

Nope, you can't go with that approach because cellForRowAtIndexPath is called many times and also it will take much time to check your conditions!

Here, I have found a better option for UITableView pagination.

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {

    //Bottom Refresh

    if scrollView == tableView{

        if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height)
        {
            if !isNewDataLoading{

                if helperInstance.isConnectedToNetwork(){

                    isNewDataLoading = true
                    getNewData()
                }
            }
        }
    }
}

isNewDataLoading is Bool to check that UITableView is loading new data or not!

Hope this helps!

查看更多
女痞
3楼-- · 2019-01-25 08:29

Try to check more data not in cellForRowAtIndexPath but in UIScrollViewDelegate - [DataModel sharedMyLibrary] is my data source class loading video data using RESTful API with pagination, it's fetchWithCompletion method fetch data from server in async, it's hasMore method says that server has more data (JSON contains next link) LibraryTableViewController - is subclass of the UITableViewController, hasMore - is the view at the bottom of the table view in the storyboard containing a button, so user has two options: scroll down or press the button. Also if this view is visible indicates that there are more data on the server. _canFetch prevents nested loading from the server.

``

@interface LibraryTableViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIView *hasMore;
@end
@implementation LibraryTableViewController
{
    __block volatile uint8_t _canFetch;
}
@synthesize hasMore = _hasMore;
- (void)viewDidLoad
{
    _canFetch = 0x80;
    [super viewDidLoad];
    [self fetchVideos:NO];
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    CGPoint offset = [scrollView contentOffset];
    if ([[DataModel sharedMyLibrary] hasMore])
    {
        if (((velocity.y > 0.0) && (offset.y > (*targetContentOffset).y)) || ((velocity.x > 0.0) && (offset.x > (*targetContentOffset).x)))
        {
            [self fetchVideos:NO];
        }
    }
    else
    {
        [_hasMore setHidden:YES];
    }
}
- (IBAction)moreVideos:(UIButton *)sender
{
    [self fetchVideos:NO];
}
- (IBAction)doRefresh:(UIRefreshControl *)sender
{
    [sender endRefreshing];
    [[DataModel sharedMyLibrary] clear];
    [self fetchVideos:YES];
}
- (void)fetchVideos:(BOOL)reload
{
    if (OSAtomicTestAndClear(0, &(_canFetch)))
    {
        __weak typeof(self) weakSelf = self;
        [[DataModel sharedMyLibrary] fetchWithCompletion:^(NSArray *indexPathes) {
            dispatch_async(dispatch_get_main_queue(), ^{
                __strong typeof(self) strongSelf = weakSelf;
                if (indexPathes != nil)
                {
                    if (reload)
                    {
                        [[strongSelf tableView] reloadData];
                    }
                    else
                    {
                        [[strongSelf tableView] beginUpdates];
                        [[strongSelf tableView] insertRowsAtIndexPaths:indexPathes withRowAnimation:UITableViewRowAnimationAutomatic];
                        [[strongSelf tableView] endUpdates];
                    }
                }
                else
                {
                    [[strongSelf tableView] reloadData];
                }
                [strongSelf->_hasMore setHidden:![[DataModel sharedMyLibrary] hasMore]];
                strongSelf->_canFetch = 0x80;
            });
        }];
    }
}

``

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-25 08:43

You should implement load more in tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath). When last cell loading is display it mean user scroll to bottom so this is time you need load more data.

Maybe it looks like this:

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    if !(indexPath.row + 1 < self.TotalRowsWithPages) {
        self.isLoading = true;
        self.getmoredata()

    }
}
查看更多
登录 后发表回答