Ios 如何知道UITableView在iPhone中何时滚动到底部

Ios 如何知道UITableView在iPhone中何时滚动到底部,ios,uitableview,scroll,Ios,Uitableview,Scroll,我想知道UITableView何时滚动到底部以加载和显示更多内容,例如委托或其他让控制器知道表格何时滚动到底部的内容 有人知道吗,请帮帮我,提前谢谢 UITableView是UIScrollView的子类,UITableViewDelegate符合UIScrollViewDelegate。因此,您附加到表视图的代理将获得诸如scrollViewDidScroll:之类的事件,并且您可以在表视图上调用诸如contentOffset之类的方法来查找滚动位置。最好的方法是测试屏幕底部的一个点,并在用户

我想知道
UITableView
何时滚动到底部以加载和显示更多内容,例如委托或其他让控制器知道表格何时滚动到底部的内容


有人知道吗,请帮帮我,提前谢谢

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

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


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

在tableview委托中执行以下操作

ObjC:

- (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");
    }
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offset = scrollView.contentOffset
    let bounds = scrollView.bounds
    let size = scrollView.contentSize
    let inset = scrollView.contentInset
    let y = offset.y + bounds.size.height - inset.bottom
    let h = size.height
    let reload_distance:CGFloat = 10.0
    if y > (h + reload_distance) {
        print("load more rows")
    }
}
Swift:

- (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");
    }
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offset = scrollView.contentOffset
    let bounds = scrollView.bounds
    let size = scrollView.contentSize
    let inset = scrollView.contentInset
    let y = offset.y + bounds.size.height - inset.bottom
    let h = size.height
    let reload_distance:CGFloat = 10.0
    if y > (h + reload_distance) {
        print("load more rows")
    }
}

上面的答案对我都没有帮助,所以我提出了以下建议:

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

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");
    }
}
-(无效)scrollViewDidScroll:(UIScrollView*)scrollView
{   
CGFloat height=scrollView.frame.size.height;
CGFloat contentYoffset=scrollView.contentOffset.y;
CGFloat DISTANCEFOMBOTTOM=scrollView.contentSize.height-contentYoffset;
if(与底部的距离<高度)
{
NSLog(“表格末尾”);
}
}

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

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


文件::

修改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");
    }
}

非常简单

我想在任意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
        }
     }
}
-(无效)ScrollViewDiEndDecelling:(UIScrollView*)scrollView
{
NSArray*cells=self.tableView.visibleCells;
nsindepath*indepath=nil;
对于(int-aIntCount=0;aIntCount<[单元格计数];aIntCount++)
{
UITableViewCell*单元格=[cells objectAtIndex:aIntCount];
CGRect cellRect=[self.tableView convertRect:cell.frame-to-view:self.tableView.superview];
if(CGRectContainsRect(self.tableView.frame,cellRect))
{
indexPath=[self.tableView indexPathForCell:cell];
//保持逻辑
}
}
}

这可能对某些人有所帮助。

我通常在最后一个单元格开始显示时使用它加载更多数据

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

我的解决方案是在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];
    }
}

Swift
中,您可以执行类似的操作。每次到达tableview的末尾时,以下条件都将为真

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

基于@Jay Mayu的答案,我认为这是一个更好的解决方案:

目标-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!");
  }
}
Swift 2.x

// UITableViewDelegate
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if (indexPath.row + 1) == sourceArray.count {
        print("Displayed the last row!")
    }
}
回答得很好,但速度很快,并对变量进行了重命名

基本上,如果
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
}

以下是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
        }
    }
Swift 3的更新

Neoneye的答案在目标C中最适合我,这与Swift 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")
    }
}
func-scrollViewWillendDraging(scrollView:UIScrollView,withVelocity:CGPoint,targetContentOffset:UnsafemeutablePointer){
let offset:CGPoint=scrollView.contentOffset
let bounds:CGRect=scrollView.bounds
let size:CGSize=scrollView.contentSize
let inset:UIEdgeInsets=scrollView.contentInset
设y:CGFloat=offset.y+bounds.size.height-inset.bottom
设h:CGFloat=size.height
//打印(“偏移量:%f”,偏移量.y)
//打印(“content.height:%f”,size.height)
//打印(“bounds.height:%f”,bounds.size.height)
//打印(“inset.top:%f”,inset.top)
//打印(“插图底部:%f”,插图底部)
//打印(“位置:%f,共%f”,y,h)
让重新加载距离:CGFloat=10
如果(y>h+重新加载距离){
打印(“加载更多行”)
}
}

@neoneye的答案对我很有用。这是它的Swift 4版本

    let offset = scrollView.contentOffset
    let bounds = scrollView.bounds
    let size = scrollView.contentSize
    let insets = scrollView.contentInset
    let y = offset.y + bounds.size.height - insets.bottom
    let h = size.height
    let reloadDistance = CGFloat(10)
    if y > h + reloadDistance {
        //load more rows
    }

不幸的是,我的应用程序将实时更新此表中现有行的数据,因此当表根本不滚动时,这种方式可能会获得更多内容。是的,这就是我所寻找的,通过实现该委托并检查滚动位置是否为UITableViewScrollPositionBottom,我将知道表何时滚动到底,非常感谢t他的解决方案除了一个小细节。如果(distanceFromBottom这帮我解决了我的问题,谢谢!!一个选项卡栏!!它是一个愚蠢的选项卡栏!!这工作很有魅力,而且也很简单,但我面临一个小问题,就像它在最后一行执行两到三次一样。如何使它在到达tableview的最后一行时只执行一次?非常感谢!!我把它放在ScrollView中的s代码将开始加速,当滚动到最后一行时,它只执行一次。您能详细说明“lastSection”的来源吗?这是用于滚动视图而不是表格好!只需使用:y>=h+reload\u distance,这实际上只是当reload\u distance=0(例如,用于反弹否)时需要考虑的问题。此代码位于“scrollViewDidScroll”中用户移动手指时一直被执行