【问题标题】:How to load more cells in UITableView SWIFT如何在 UITableView SWIFT 中加载更多单元格
【发布时间】:2016-02-23 13:15:07
【问题描述】:

我有一个UITableViewController(而不是PFQueryTableViewController)来显示我的查询结果,并且我有一个存储文本的数组。由于查询会获取大量数据,我希望我的tableView 在用户滚动到底部后加载更多结果。那里有很多解决方案,但它们要么是 JSON 要么是 ObjectiveC,它们对我来说似乎真的很模糊,因为我只是一个初学者。

class queryResultsViewController: UITableViewController {

var texts = [String]()


override func viewDidLoad() {
    super.viewDidLoad()

    let query = PFQuery(className: "allPosts")

    query.whereKey("userId", equalTo: (PFUser.currentUser()?.objectId)!)
    query.orderByDescending("createdAt")

    query.findObjectsInBackgroundWithBlock { (posts, error) -> Void in

        if let posts = posts {

            self.texts.removeAll(keepCapacity: true)

            for post in posts {

                self.captionOne.append(post["text"] as! String)

                self.tableView.reloadData()
            }
        }
    }
}

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return texts.count
}


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

    cell.TextView.text = texts[indexPath.row]

    return cell
}

【问题讨论】:

  • 那个叫无限滚动,去github试试。如果没有必要,不要自己造轮子。

标签: swift uitableview pfquery


【解决方案1】:

要检测用户何时滚动到UITableView底部,可以实现UIScrollView委托方法scrollViewDidScroll:

一个示例实现(从:https://stackoverflow.com/a/5627837/3933375 转换为 Swift)

override func scrollViewDidScroll(scrollView: UIScrollView) {
    let offset = scrollView.contentOffset
    let bounds = scrollView.bounds
    let size = scrollView.contentSize
    let inset = scrollView.contentInset
    let y = CGFloat(offset.y + bounds.size.height - inset.bottom)
    let h = CGFloat(size.height)

    let reload_distance = CGFloat(10)
    if(y > (h + reload_distance)) {
        print("load more rows")
    }
}

当这触发时,您可以从解析中下载更多结果,将它们添加到您的 UITableView 的数据源并调用重新加载数据。

此外,查看您的代码时,您可能需要调用 dispatch_async,因为您尝试在后台块中更新 UI,例如

dispatch_async(dispatch_get_main_queue()) { () -> Void in
        self.tableview.reloadData()
    }



编辑
从 Parse 加载更多结果

let query = PFQuery(className: "allPosts")

query.whereKey("userId", equalTo: (PFUser.currentUser()?.objectId)!)
query.orderByDescending("createdAt")

query.limit = 50 // or your choice of how many to download at a time (defaults to 100)
query.skip = 50 // This will skip the first 50 results and return the next limit after. If

query.makeRequest......



在您的完成处理程序中,确保将结果附加到整个数据源(在您的情况下为 texts),然后调用重新加载数据。

【讨论】:

  • 感谢您的回复。关于下载更多结果,我应该如何构建我的 PFQuery?比如我怎样才能确保我正在下载额外的数据,而不是包括我已经下载的数据在内的一大堆数据?
  • @H.Lamb 我已经编辑了我的答案,简而言之,您可以使用query.limit 设置您想要接收的结果数量,并使用query.skip 来获取后面的下一个 z 元素第一组。
  • 嘿,我很抱歉打扰,但刚刚发现使用 scrollViewDidScroll 基金会触发两次查询?重新加载 tableview 后,两组相同的查询结果被加载到 tableview,知道为什么会发生这种情况吗?我关闭了解析本地数据存储以避免cacheThenNetwork,不知道这是否相关
  • 我认为这不会影响它。我会在文件顶部添加一个布尔变量,以便在 parse 发出请求时进行跟踪,然后仅在该请求完成时再创建一个。所以在scrollViewDidScroll 中,您首先要检查该变量以查看当前是否有正在进行的请求
  • 请不要忘记在请求完成时再次将 requestInProgress 变量设置为 false。试一试,如果您有任何问题,请告诉我,我会在答案中添加更详细的内容。
【解决方案2】:

仅显示 20 行(例如)并在屏幕底部的 UIToolBar 中添加一个“下一步”按钮怎么样?当用户点击按钮时,您会显示第 21-40 行等。您还可以添加“上一个”按钮以向后移动。

- (void)setUpToolbar
{
// add a toolbar with a prev and next button
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @""
                                                                         style: UIBarButtonItemStylePlain
                                                                        target: nil
                                                                        action: nil];

UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace
                                                                              target: nil
                                                                              action: nil];

self.prevButton = [[UIBarButtonItem alloc] initWithTitle: NSLocalizedString(@"Prev", nil)
                                                   style: UIBarButtonItemStylePlain
                                                  target: self
                                                  action: @selector(clickedPrevButton:)];

self.nextButton = [[UIBarButtonItem alloc] initWithTitle: NSLocalizedString(@"Next", nil)
                                                   style: UIBarButtonItemStylePlain
                                                  target: self
                                                  action: @selector(clickedNextButton:)];

self.nextButton.enabled = NO;
self.prevButton.enabled = NO;
self.page = 1;

self.toolbarItems = @[self.prevButton, flexibleItem, self.nextButton];
}

- (void) clickedNextButton: (id) sender
{    
if ([self.nextButton.title isEqualToString: NSLocalizedString(@"More Results", nil)])
{
    self.offset += kSearchLimit;
    self.nextButton.title = NSLocalizedString(@"Next", nil);
    self.page += 1;

    [self searchDatabase];
}
else
{
    self.page += 1;

    if ((self.page - 1) * kEntriesToDisplay > self.searchResults.count)
    {
        self.nextButton.enabled = NO;
    }

    if (self.page * kEntriesToDisplay == self.searchResults.count)
    {
        self.nextButton.enabled = YES;
        self.nextButton.title = NSLocalizedString(@"More Results", nil);
    }

    self.prevButton.enabled = YES;

    [self updateSearchUI];        
}
}

- (void) clickedPrevButton: (id) sender
{
self.page -= 1;

if (self.page == 1)
    self.prevButton.enabled = NO;

self.nextButton.title = NSLocalizedString(@"Next", nil);
self.nextButton.enabled = YES;

[self updateSearchUI];
}

【讨论】:

  • 这听起来也像是一个计划。我应该如何实现这一目标?
  • 我添加了一些我在项目中使用的示例代码。抱歉,它位于ObjectiveC,但希望您可以以此为起点。
【解决方案3】:

这是在UITableView 中处理load more 的正确方法。 为避免波动,当滚动视图停止时调用以下方法。

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    let scrollHeight = scrollView.frame.size.height

    let endScrolling = offsetY + scrollHeight

    if endScrolling >= scrollView.contentSize.height {
        //Load more logic
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-21
    • 2015-04-10
    • 2017-09-12
    • 2020-07-14
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多