当用户滚动到最后一个 tableViewCell 时执行操作

Posted

技术标签:

【中文标题】当用户滚动到最后一个 tableViewCell 时执行操作【英文标题】:Do action when user scrolls to last tableViewCell 【发布时间】:2015-07-21 05:35:56 【问题描述】:

上下文

构建一种新闻源

问题

当用户滚动到最后一个表格视图单元格时,我需要加载更多帖子 我不知道从哪里开始,如何实现,代码在哪里 所以基本上我需要在用户滚动到最后一个表格视图时调用服务器下载帖子,将这些帖子附加到当前表格视图的底部

这是相关的代码片段(我想!)

class GeneralPostAreaController: UIViewController 
        ...
        extension GeneralPostAreaController: UITableViewDataSource 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        return PostsCollection.postsFromParse.posts.count

    

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostTableViewCell
        cell.postImage.image = PostsCollection.postsFromParse.posts[indexPath.row].image
        cell.postName.text = PostsCollection.postsFromParse.posts[indexPath.row].name
        cell.postText.text = PostsCollection.postsFromParse.posts[indexPath.row].text

        cell.loadAudio = PostsCollection.postsFromParse.posts[indexPath.row].audioObject.parseAudioData
        return cell
    


这是我用来从服务器(解析)获取数据的代码。原谅可怕的数据结构,这是我的第一个应用程序!

    class ParseQueryer: NSObject

//HAVE TO RESTRUCTURE

var posts: [Post] = []

//this is not a very elegant way to reload table Data
func getPosts(selectedTableView: UITableView)

var query = PFQuery(className: "Post")
query.addDescendingOrder("createdAt")
query.limit = 10
query.findObjectsInBackgroundWithBlock (result: [AnyObject]?, error: NSError?) -> Void in
    self.posts = result as? [Post] ?? []

    selectedTableView.reloadData()

    for post in self.posts
        post.name = post["Name"] as? String
        post.text = post["Text"] as? String
        //println(post.text)
        if let audioData = post["Audio"] as? PFFile 
            audioData.getDataInBackgroundWithBlock(
                (audioData: NSData?, error: NSError?) -> Void in
                if (error == nil)
                    post.audioObject.parseAudioData = audioData
                
            )
        
        if let imgData = post["Photo"] as? PFFile 
            imgData.getDataInBackgroundWithBlock(
                (imageData: NSData?, error: NSError?) -> Void in
                if (error == nil)
                    let image = UIImage(data: imageData!)
                    post.image = image
                
            )
        

    

    selectedTableView.reloadData()

我查看了答案here,但这对我来说没有意义。

【问题讨论】:

【参考方案1】:

所以UITableView 继承自UIScrollView,因此您可以使用滚动视图委托方法来了解您何时滚动到底部。

    override func scrollViewDidScroll(scrollView: UIScrollView) 

       //1. decide on the distance from the bottom that if the user scrolls to that point you will load more results
        let minimumTrigger = scrollView.bounds.size.height + self.triggerDistanceFromBottom

        // 2. Now you are checking to see that the height of all the content in the scrollview/tableView.( i.e. all the cells hights stacked ontop of eachother) is greater than the minimum height for triggering a load
       // This step is so that if you have only a few results, the loadMoreResults method won't constantly be called. 
        if scrollView.contentSize.height > minimumTrigger 

           //3. This calculated the distance from the bottom of the scrollview. 
            let distanceFromBottom = scrollView.contentSize.height - (scrollView.bounds.size.height - scrollView.contentInset.bottom) - scrollView.contentOffset.y

            //4. then this is the crucial check.
            if distanceFromBottom < self.scrollTriggerDistanceFromBottom 
                // Do your stuff
            
        

    

【讨论】:

【参考方案2】:

您可以通过这种方法进行加载更多操作,因为表格视图委托是滚动视图委托:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

    float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (bottomEdge >= scrollView.contentSize.height)
    
        // we are at the end

       if(currentCount<pageCount)
       
           if(isLoading)
           
               return;
           
           UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
           [spinner startAnimating];
           spinner.frame = CGRectMake(0, 22, 50, 44);
           self.tblCentreEvents.tableFooterView = spinner;

            isLoading=TRUE;
           dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^
               [self populateDataInList];

           );


       

    

【讨论】:

【参考方案3】:

最好的方法是在屏幕底部测试一个点,并在用户滚动时使用此方法调用 (scrollViewDidScroll):

- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point

测试屏幕底部附近的一个点,然后使用它返回的 indexPath 检查该 indexPath 是否是最后一行,如果是,则添加行。

【讨论】:

以上是关于当用户滚动到最后一个 tableViewCell 时执行操作的主要内容,如果未能解决你的问题,请参考以下文章

当用户使用 UITableView 的后退按钮滚动到最后选定的行时

我可以在 tableviewcell 中发现 tableview 手势识别器的状态吗

swift:TableViewCell 在滚动之前不会更新约束

如何正确加载依赖的 tableViewCell API 数据?

如何检测WinForms Panel是否已滚动到最后?

如何滚动到第一个单元格,同时在 CollectionView 上滑动最后一个单元格?