Как узнать, когда UITableView сделал прокрутку вниз в iPhone
Я хотел бы знать, когда UITableView
сделал прокрутку вниз, чтобы загрузить и показать больше контента, что-то вроде делегата или что-то еще, чтобы контроллер знал, когда таблица прокрутилась вниз.
кто-нибудь знает это, пожалуйста, помогите мне, заранее спасибо!
16 ответов:
лучший способ-проверить точку в нижней части экрана и использовать этот метод вызова, когда пользователь прокручивает (
scrollViewDidScroll
):- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
Проверьте точку в нижней части экрана, а затем с помощью 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 ответить немного.
этот ответ предназначен для тех из вас, кто хочет, чтобы событие было вызвано только один раз за выпуск пальца.
подходит при загрузке большего количества контента от какого-либо поставщика контента (веб-службы, основных данных и т. д.). Обратите внимание, что этот подход не учитывает время отклика от веб-службы.
- (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"); } }
ни один из ответов выше не помог мне, поэтому я придумал это:
- (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 } }
использовать
– tableView:willDisplayCell:forRowAtIndexPath:
(UITableViewDelegate
способ)просто сравнить
indexPath
с элементами в вашем массиве данных (или любом источнике данных, который вы используете для своего табличного представления), чтобы выяснить, отображается ли последний элемент.
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
вы можете сделать что-то подобное. Следующее условие будет истинным каждый раз, когда вы достигнете конца tableviewfunc tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if indexPath.row+1 == postArray.count { println("came to last row") } }
основываясь на ответе @Jay Mayu, который, как я чувствовал, был одним из лучших решений:
С
// 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!") } }
Я обычно использую это, чтобы загрузить больше данных, когда последняя ячейка начинает отображать
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == myDataArray.count-1) { NSLog(@"load more"); } }
С neoneye отличные ответы, но в swift, и переименование переменных..
в основном мы знаем, что мы достигли нижней части таблицы, если
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 } }
мое решение состоит в том, чтобы добавить ячейки до того, как 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
ответ Neoneye лучше всего работал для меня в Objective 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") } }
Я хочу, чтобы выполнить какое-либо действие на мой любой 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 } } }
пусть это поможет кому-то.