Відповіді:
Найкращий спосіб - перевірити точку в нижній частині екрана і використовувати цей метод виклику, коли користувач прокручує ( scrollViewDidScroll):
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
Тестуйте крапку внизу екрана, а потім, використовуючи indexPath, вона повертається, перевірте, чи є цей indexPath останнім рядком, а якщо він є, додайте рядки.
у представника таблиці перегляду роблять щось подібне
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")
}
}
Змінені неонеї трохи відповідають.
Ця відповідь націлена на тих із вас, хто хоче, щоб подію було розпочато лише один раз при звільненні пальця .
Підходить під час завантаження більше вмісту від деякого постачальника контенту (веб-сервіс, основні дані тощо). Зауважте, що такий підхід не враховує час відповіді вашого веб-сервісу.
- (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вас можна зробити щось подібне. Виконання цієї умови буде дотримано кожного разу, коли ви досягнете кінця подання таблиці
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row+1 == postArray.count {
println("came to last row")
}
}
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!");
}
}
Швидкий 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");
}
}
Отримання неоні- чудових відповідей, але швидко та перейменування змінних.
В основному ми знаємо, що ми досягли нижнього перегляду таблиці, якщо значення 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
}
Ось швидкий код версії 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
}
}
Моє рішення полягає в тому, щоб додати комірки до того, як перегляд таблиці зменшиться за прогнозованим зміщенням. Це прогнозовано на швидкості.
- (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», це еквівалент відповіді у 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
}
}
}
Нехай це допоможе комусь.
@ 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
}