2011-02-28 22 views

回答

17

最好的办法是在屏幕底部的测试点,并用这个方法调用当过用户滚动(scrollViewDidScroll):

- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point 

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

在的tableview委托
+0

不幸的是,我的Ap p将实时更新此表中现有行的数据,因此当表格完全不滚动时,这种方式可能会获得更多内容。 – 2011-02-28 03:58:30

13

UITableViewUIScrollView的子类,并且UITableViewDelegate符合UIScrollViewDelegate。因此,您附加到表视图的代表将获得诸如scrollViewDidScroll:之类的事件,并且您可以在表视图上调用诸如contentOffset之类的方法来查找滚动位置。

+0

是的,这是我在找什么,通过实现委托并检查滚动位置是否为UITableViewScrollPositionBottom,我将知道表何时滚动到底部,非常感谢 – 2011-02-28 04:07:27

243

做这样的事情

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView { 
    CGPoint offset = aScrollView.contentOffset; 
    CGRect bounds = aScrollView.bounds; 
    CGSize size = aScrollView.contentSize; 
    UIEdgeInsets inset = aScrollView.contentInset; 
    float y = offset.y + bounds.size.height - inset.bottom; 
    float h = size.height; 
    // NSLog(@"offset: %f", offset.y); 
    // NSLog(@"content.height: %f", size.height); 
    // NSLog(@"bounds.height: %f", bounds.size.height); 
    // NSLog(@"inset.top: %f", inset.top); 
    // NSLog(@"inset.bottom: %f", inset.bottom); 
    // NSLog(@"pos: %f of %f", y, h); 

    float reload_distance = 10; 
    if(y > h + reload_distance) { 
     NSLog(@"load more rows"); 
    } 
} 
+2

非常有帮助的职位。干杯。 – Echilon 2011-09-06 14:26:49

+0

非常有帮助!谢谢你不要做数学。 – Johnny 2013-03-09 08:03:12

+0

为什么不是这个选择的答案? – 2014-02-13 19:16:48

18

的答案上面帮我没有,所以我想出了这个:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)aScrollView 
{ 
    NSArray *visibleRows = [self.tableView visibleCells]; 
    UITableViewCell *lastVisibleCell = [visibleRows lastObject]; 
    NSIndexPath *path = [self.tableView indexPathForCell:lastVisibleCell]; 
    if(path.section == lastSection && path.row == lastRow) 
    { 
     // Do something here 
    } 
} 
+0

您能否详细说明“lastSection”的来源? – ainesophaur 2013-11-27 20:43:15

+0

这是为滚动视图而不是表 – iosMentalist 2014-09-22 14:58:00

38

UITableViewDelegate添加这个方法:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    CGFloat height = scrollView.frame.size.height; 

    CGFloat contentYoffset = scrollView.contentOffset.y; 

    CGFloat distanceFromBottom = scrollView.contentSize.height - contentYoffset; 

    if(distanceFromBottom < height) 
    { 
     NSLog(@"end of the table"); 
    } 
} 
+3

我喜欢这个解决方案,除了一个小细节。如果(distanceFromBottom <= height) – 2013-03-14 19:40:14

+0

这帮助我解决了我的问题,谢谢!一个标签栏!这是一个愚蠢的标签栏! – Dmytro 2016-05-17 04:40:24

+0

这项工作就像一个魅力,它也很简单,但我面临一个小问题,就像它在最后一排执行两三次一样。如何在它到达tableview的最后一行时只执行一次? – 2017-07-28 11:11:26

19

使用– tableView:willDisplayCell:forRowAtIndexPath:UITableViewDelegate方法)

只需将indexPath与您的数据数组中的项目(或您用于表格视图的任何数据源)进行比较,以确定是否显示最后一个元素。

文档:http://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:willDisplayCell:forRowAtIndexPath

+0

然后,如果您重新加载tableView的数据,您将陷入无限循环。 – 2016-11-17 11:30:14

59

修改neoneyes回答了一下。

此答案针对那些只希望事件被触发一次的人每个版本的手指

适用于从某些内容提供者(Web服务,核心数据等)加载更多内容时。 请注意,此方法不考虑来自Web服务的响应时间。

- (void)scrollViewDidEndDragging:(UIScrollView *)aScrollView 
        willDecelerate:(BOOL)decelerate 
{ 
    CGPoint offset = aScrollView.contentOffset; 
    CGRect bounds = aScrollView.bounds; 
    CGSize size = aScrollView.contentSize; 
    UIEdgeInsets inset = aScrollView.contentInset; 
    float y = offset.y + bounds.size.height - inset.bottom; 
    float h = size.height; 

    float reload_distance = 50; 
    if(y > h + reload_distance) { 
     NSLog(@"load more rows"); 
    } 
} 
+4

真棒工作@eyeball ..你的回答是完美的..至少在我的观点。 – harshitgupta 2014-03-28 04:34:32

+0

这不起作用。无论用户何时滚动到底部,都会调用“加载更多行”。即使用户已经滚动到底部并且正在等待API返回数据,也会发生这种情况。 – Dean 2014-07-14 06:45:10

+2

院长,问题是要知道什么时候表格视图滚动到底部。无论您是从API获取数据还是不相关,都不是吗? – Eyeball 2014-07-14 08:49:23

7
NSLog(@"%f/%f",tableView.contentOffset.y, tableView.contentSize.height - tableView.frame.size.height); 

if (tableView.contentOffset.y == tableView.contentSize.height - tableView.frame.size.height) 
     [self doSomething]; 

尼斯和简单

2

我想对我的任何1个整体Tableviewcell执行某些操作。

因此代码链接:

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    NSArray* cells = self.tableView.visibleCells; 
    NSIndexPath *indexPath = nil ; 

    for (int aIntCount = 0; aIntCount < [cells count]; aIntCount++) 
    { 

     UITableViewCell *cell = [cells objectAtIndex:aIntCount]; 
CGRect cellRect = [self.tableView convertRect:cell.frame toView:self.tableView.superview]; 

     if (CGRectContainsRect(self.tableView.frame, cellRect)) 
     { 
      indexPath = [self.tableView indexPathForCell:cell]; 

    // remain logic 
     } 
    } 
} 

愿这是帮助其他人。

5

我一般用此来当最后小区开始显示

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (indexPath.row == myDataArray.count-1) { 
     NSLog(@"load more"); 
    } 
} 
+1

这是错误的。每次调用reloadData时都会发出请求。有时你只需要重新加载表格。 – 2015-03-18 07:56:29

+0

你想说,如果你在最后一个单元格,然后重新加载数据,那么这会发生? – 2015-03-18 12:50:44

3

我的解决方案是增加细胞之前的tableview将在估计出的偏移加载减速更多的数据,。它可以通过速度预测。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)offset { 

    NSLog(@"offset: %f", offset->y+scrollView.frame.size.height); 
    NSLog(@"Scroll view content size: %f", scrollView.contentSize.height); 

    if (offset->y+scrollView.frame.size.height > scrollView.contentSize.height - 300) { 
     NSLog(@"Load new rows when reaches 300px before end of content"); 
     [[DataManager shared] fetchRecordsNextPage]; 
    } 
} 
+0

它工作正常:-) – 2017-07-28 11:25:38

7

Swift你可以这样做。以下情况将是真实的,每次你到达的tableview结束

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
     if indexPath.row+1 == postArray.count { 
      println("came to last row") 
     } 
} 
+0

问题是,当tableview只有3个单元格,例如'println(“来到最后一行”)'这个代码运行! – 2017-11-04 15:12:13

5

上@Jay抹于的答案,我觉得建筑是更好的解决方案之一:

Objective-C的

// UITableViewDelegate 
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 

// Need to call the service & update the array 
if(indexPath.row + 1 == self.sourceArray.count) { 
    DLog(@"Displayed the last row!"); 
    } 
} 

斯威夫特2.x的

// UITableViewDelegate 
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    if (indexPath.row + 1) == sourceArray.count { 
     print("Displayed the last row!") 
    } 
} 
5

neoneye优秀的答案,但在迅速的,和变量的重命名..

基本上,我们知道我们已经到了表视图的底部,如果yOffsetAtBottom超出了表格内容的高度。

func isTableViewScrolledToBottom() -> Bool { 
    let tableHeight = tableView.bounds.size.height 
    let contentHeight = tableView.contentSize.height 
    let insetHeight = tableView.contentInset.bottom 

    let yOffset = tableView.contentOffset.y 
    let yOffsetAtBottom = yOffset + tableHeight - insetHeight 

    return yOffsetAtBottom > contentHeight 
} 
5

这里是swift 3.0版本的代码。

func scrollViewDidScroll(_ scrollView: UIScrollView) { 

     let offset = scrollView.contentOffset 
     let bounds = scrollView.bounds 
     let size = scrollView.contentSize 
     let inset = scrollView.contentInset 
     let y: Float = Float(offset.y) + Float(bounds.size.height) + Float(inset.bottom) 
     let height: Float = Float(size.height) 
     let distance: Float = 10 

     if y > height + distance { 
      // load more data 
     } 
    } 
3

更新斯威夫特3

Neoneye的答案目标C的工作最适合我,这就是答案的斯威夫特卡伦特3等价的:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    let offset: CGPoint = scrollView.contentOffset 
    let bounds: CGRect = scrollView.bounds 
    let size: CGSize = scrollView.contentSize 
    let inset: UIEdgeInsets = scrollView.contentInset 
    let y: CGFloat = offset.y + bounds.size.height - inset.bottom 
    let h: CGFloat = size.height 
//  print("offset: %f", offset.y) 
//  print("content.height: %f", size.height) 
//  print("bounds.height: %f", bounds.size.height) 
//  print("inset.top: %f", inset.top) 
//  print("inset.bottom: %f", inset.bottom) 
//  print("position: %f of %f", y, h) 

    let reloadDistance: CGFloat = 10 

    if (y > h + reloadDistance) { 
      print("load more rows") 
    } 
} 
相关问题