【问题标题】:UITableView Pagination - Bottom Refresh to Load New Data in SwiftUITableView 分页 - 底部刷新以在 Swift 中加载新数据
【发布时间】:2016-05-31 11:05:33
【问题描述】:

我正在尝试通过分页实现从后端加载数据。我已经看到了这个,但是它加载了所有的数据,一直都是这样。这是正确的方法还是我做错了什么?

提前致谢。

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
}

【问题讨论】:

    标签: ios swift swift3 swift2


    【解决方案1】:

    不,您不能采用这种方法,因为cellForRowAtIndexPath 被多次调用,而且检查您的条件需要很长时间!

    在这里,我为UITableView 分页找到了更好的选择。

    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()
                    }
                }
            }
        }
    }
    

    isNewDataLoadingBool 以检查 UITableView 是否正在加载新数据!

    希望这会有所帮助!

    【讨论】:

    • @UtkuDalmaz 你能告诉我到底是什么不工作吗?
    • 二元运算符“==”不能应用于“UIScrollView”和“_”类型的操作数
    • 你能解释一下这个例子中的 helperInstance.isConnectedToNetwork() 是什么吗?
    • @Abrcd18 这只是检查互联网连接的常用方法。看看我们没有在互联网不可用的情况下调用 API。
    • 我有表格视图,但没有滚动视图。那么我应该如何使用这个功能呢?提前致谢。
    【解决方案2】:

    您应该在tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) 中实现加载更多。当显示最后一个单元格加载时,这意味着用户滚动到底部,因此您需要加载更多数据。

    也许它看起来像这样:

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    
        if !(indexPath.row + 1 < self.TotalRowsWithPages) {
            self.isLoading = true;
            self.getmoredata()
    
        }
    }
    

    【讨论】:

    • 我已经尝试过这种方法。无论用户在哪里,都会调用willDisplayCell。当您在 tableview 中重新加载数据时,将为每一行调用 willDisplayCell。接受的答案很完美。
    【解决方案3】:

    尝试检查更多不是在 cellForRowAtIndexPath 中而是在 UIScrollViewDelegate 中的数据 - [DataModel sharedMyLibrary] 是我的数据源类,它使用带有分页的 RESTful API 加载视频数据,它是 fetchWithCompletion 方法从服务器异步获取数据,它的 hasMore 方法表示服务器有更多数据(JSON 包含下一个链接) LibraryTableViewController - 是 UITableViewController 的子类,hasMore - 是故事板中表格视图底部的视图,包含一个按钮,因此用户有两个选择:向下滚动或按下按钮。此外,如果此视图可见,则表明服务器上有更多数据。 _canFetch 防止从服务器进行嵌套加载。

    ``

    @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;
                });
            }];
        }
    }
    

    ``

    【讨论】:

    • 问题属于Swift所以请不要发布不必要的代码。如果你有Swift 代码,那就去吧,否则删除答案
    • @SohilR.Memon,这家伙想帮忙,是的,不是Swift,但背后的逻辑是一样的。
    • @0yeoj 但是这家伙刚刚发布了完整的代码,这个人将如何理解。如果他/她试图解释逻辑,那么答案中应该只提到那部分。我的意图是解决提出问题的人的问题。不过没有冒犯!
    • @SohilR.Memon,他上面有一个标题。但我明白你的意思,他本可以添加 cmets 并解释发生了什么。 (如果提问的人不了解ObjC 怎么办),至少我们指出这件事......干杯! ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2012-01-19
    相关资源
    最近更新 更多