如何知道UITableView在iPhone中滚动到底的时间
我想知道什么时候UITableView
滚动到底部,以加载和显示更多的内容,像委托或其他东西,让控制器知道什么时候表滚动到底部。
有谁知道这一点,请帮助我,在此先感谢!
最好的方法是在屏幕底部testing一个点,并在用户滚动时使用此方法调用( scrollViewDidScroll
):
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
testing屏幕底部附近的一个点,然后使用indexPath检查indexPath是否是最后一行,如果是,则添加行。
在tableview委托做这样的事情
- (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"); } }
修改的neoneyes回答了一下。
这个答案是针对那些只希望在每次释放手指时触发一次事件的人 。
从某些内容提供者(networking服务,核心数据等)加载更多内容时适用。 请注意,这种方法不考虑来自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"); } }
在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"); } }
使用– 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 :
上面的答案都没有帮助我,所以我想出了这个:
- (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 } }
UITableView
是UIScrollView
的子类, UITableViewDelegate
符合UIScrollViewDelegate
。 因此,您附加到表视图的委托将获得诸如scrollViewDidScroll:
事件,并且您可以在表视图上调用诸如contentOffset
方法来查找滚动位置。
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];
好而简单
在Swift
你可以做这样的事情。 每当你到达tableview的结尾时,下面的条件都是正确的
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if indexPath.row+1 == postArray.count { println("came to last row") } }
我通常使用这个来加载更多的数据,当最后一个单元格开始显示
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == myDataArray.count-1) { NSLog(@"load more"); } }
build立在@Jay Mayu的答案,我觉得是更好的解决scheme之一:
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!"); } }
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!") } }
以neoneye优秀的答案,但迅速,并重新命名的variables..
基本上我们知道,如果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 } }
我的解决scheme是添加单元格之前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 3的更新
目标C中Neoneye的答案对我来说效果最好,这相当于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("pos: %f of %f", y, h) let reload_distance:CGFloat = 10 if(y > h + reload_distance) { print("load more rows") } }
我想在我的任何一个完整的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 } } }
可能这是对某个人的帮助。