【问题标题】:Add rows to UITableView when scrolled to bottom滚动到底部时向 UITableView 添加行
【发布时间】:2011-08-26 18:59:51
【问题描述】:

当用户滚动到UITableView 的底部时,有没有办法触发事件,例如使用IBAction?如果发生这种情况,我想添加更多行。我该怎么做?

【问题讨论】:

标签: objective-c cocoa-touch ios uitableview


【解决方案1】:

斯威夫特

这是@user944351's answer的Swift版本:

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    
    let currentOffset = scrollView.contentOffset.y
    let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
    
    if maximumOffset - currentOffset <= -40 {
        print("reload")
    }
}

只需将此方法添加到您的UITableView 委托类。我发现-40 太大了,但你可以根据需要调整它。

更多信息

  • 请参阅my fuller answer,其中包含使用数据库的限制和偏移量重新加载数据的方法示例。

【讨论】:

  • 这是系统调用的回调函数吗?
【解决方案2】:

只需收听scrollViewDidScroll: 委托方法,将内容偏移量与当前可能的偏移量进行比较,如果低于某个阈值,则调用您的方法来更新表格视图。不要忘记致电[tableView reloadData] 以确保它重新加载新添加的数据。

编辑:将抽象代码放在一起,不确定它是否有效,但应该。

- (void)scrollViewDidScroll: (UIScrollView *)scroll {
     // UITableView only moves in one direction, y axis
     CGFloat currentOffset = scroll.contentOffset.y;
     CGFloat maximumOffset = scroll.contentSize.height - scroll.frame.size.height;

     // Change 10.0 to adjust the distance from bottom
     if (maximumOffset - currentOffset <= 10.0) {
          [self methodThatAddsDataAndReloadsTableView];
     }
}

【讨论】:

  • 没有项目 atm 可以快速显示某些内容。我认为您的 viewController 是 tableView 的委托。如果是这样,只需将 scrollViewDidScroll: 添加到 viewController 并将其用作触发更新方法的位置。比较 contentOffset.y 和最大值(contenSize.y - tableView.frame.size.height)应该很简单。
  • 关键是要意识到 UITableView 是 UIScrollView 的子类,它也传递了委托方法。
  • 一旦滚动停止就会触发,还是在滚动时也会执行?
  • 我相信每次 contentOffset 改变都会触发这个,这意味着如果你滚动,这会被触发很多。这提醒了我,如果您正在从网络发出请求,您可能应该暂时禁用该系统,当请求正在进行时,一旦添加了内容,就可以重新启用。只需在 isUpdating 某处添加一个布尔值并检查偏移量差异。
  • 为什么还要触发方法[self methodThatAddsDataAndReloadsTableView];
【解决方案3】:

我猜它可以通过更简单的方式实现,您只需要确定滚动方向,在这种情况下,它是当用户向下滚动时。

首先在您的 .h 文件中声明一个变量:

CGPoint pointNow;

在.m文件中,在scrollViewDidScroll方法中我们需要实现这段代码:-

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y > pointNow.y) {
        //Enter code here
    }
}

【讨论】:

    【解决方案4】:

    我用这个sn-p。在tableView:willDisplayCell:forRowAtIndexPath: 中,我检查是否将显示具有最后一个索引路径的单元格。

    对于只有一个部分的 tableView:

    [indexPath isEqual:[NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]-1 inSection:0]
    

    更多部分:

    [indexPath isEqual:[NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]-1 inSection:[self numberOfSectionsInTableView:self.tableView]-1]
    

    -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(!_noMoreDataAvailable)
        {
            if ([indexPath isEqual:[NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]-1 inSection:0]])
            {
                [self.dataSourceController fetchNewData];
            }
        }
    }
    

    获取 dataSourceController 后会通知 tableView 委托,这将重新加载数据。

    【讨论】:

    • 出色的答案,更喜欢这个比较的 scrollViewDidScroll 选项 - 感谢 vikingosegundo!
    • 如果您使用加载或错误单元格,请务必进行小检查,例如:if(indexPath.row > 5) 或简单地将布尔 noMoreDataAvailble 设置为 false。
    • 如果您想在用户到达最后一个单元格之前稍微加载数据,这不是很好。我发现当你在几个单元之前加载它时它“流动”更好
    • @Tander,您应该可以将其更改为较早的 indexPath。
    【解决方案5】:

    除非有点晚,但我想我找到了更好的解决方案:

    而不是

     - (void)scrollViewDidScroll: (UIScrollView)scroll
    

    我用过

    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    

    这样方便多了,因为事件只触发一次。 我在我的应用程序中使用此代码在底部的表格视图中加载更多行(也许您认识到这种类型的从 facebook 应用程序重新加载 - 唯一的区别是它们在顶部更新)。

    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {    
        NSInteger currentOffset = scrollView.contentOffset.y;
        NSInteger maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;
    
        if (maximumOffset - currentOffset <= -40) {
            NSLog(@"reload");
        }
    }
    

    希望有人能帮忙。

    【讨论】:

    • 这就是我只需要对我的服务器进行一次调用。 - (void)scrollViewDidScroll: 被触发多次以调用您的服务器。除非您按照上面在他的 cmets 中建议的@Henri Normak 进行操作并添加检查以进行更新。这要简单得多。谢谢@user944351
    • 我对此进行了测试,但它仅在表格视图已经接近底部时开始拖动时才有效。如果是长卷轴,即使正好在底部结束也不满足 if 条件。
    • 有意义,因为该方法称为“结束拖动”,所以我认为在用户结束拖动手势时使用偏移量调用。但列表可以继续滚动。它应该在到达底部时自动加载,所以看起来scrollViewDidScroll 是正确的。
    • swift 3 中的相同代码 let currentOffset: Int = Int(scrollView.contentOffset.y) let maximumOffset = Int(scrollView.contentSize.height - scrollView.frame.size.height) if maximumOffset - currentOffset
    【解决方案6】:

    我不确定您为什么要这样做,但我想您可以在 cellForRowAtIndexPath 方法中添加一些代码,这样如果 indexPath.row == 最后一行,则调用该方法来添加更多行...

    【讨论】:

    • 因为我想调用 REST Web 服务来添加更多行,因为用户可以看到更多条目,而不是“加载更多帖子”之类的东西,为什么不自动完成
    【解决方案7】:
    NSInteger currentOffset = scrollView.contentOffset.y;
    NSInteger maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;
    
    // Hit Bottom?
    if ((currentOffset > 0) && (maximumOffset - currentOffset) <= 10) {
       // Hit Bottom !! 
    }
    

    【讨论】:

      猜你喜欢
      • 2018-03-17
      • 2016-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多