Comment savoir quand UITableView a fait défiler vers le bas dans iPhone

Je voudrais savoir quand un UITableView fait défiler vers le bas pour charger et afficher plus de contenu, quelque chose comme un délégué ou quelque chose d’autre pour laisser le contrôleur savoir quand la table fait défiler vers le bas.

Est-ce que quelqu’un le sait, aidez-moi s’il vous plaît, merci d’avance!

Le meilleur moyen est de tester un point en bas de l’écran et d’utiliser cet appel de méthode lorsque l’utilisateur fait défiler ( scrollViewDidScroll ):

 - (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point 

Testez un point situé près du bas de l’écran, puis, à l’aide de l’indexPath, il vérifie si l’indexPath est la dernière ligne. Si c’est le cas, ajoutez des lignes.

dans le délégué tableview faire quelque chose comme ça

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

Les neoney modifiés répondent un peu.

Cette réponse cible ceux d’entre vous qui souhaitent uniquement que l’événement soit déclenché une fois par relâchement du doigt .

Convient au chargement de plus de contenu à partir d’un fournisseur de contenu (service Web, données de base, etc.). Notez que cette approche ne respecte pas le temps de réponse de votre service 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"); } } 

Ajoutez cette méthode dans 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"); } } 

Use – tableView:willDisplayCell:forRowAtIndexPath: (méthode UITableViewDelegate )

Il vous suffit de comparer l’ indexPath avec les éléments de votre tableau de données (ou la source de données que vous utilisez pour l’affichage de votre table) pour déterminer si le dernier élément est affiché.

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

Aucune des réponses ci-dessus ne m’a aidé, alors j’ai trouvé ceci:

 - (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 est une sous-classe de UIScrollView et UITableViewDelegate est conforme à UIScrollViewDelegate . Ainsi, le délégué que vous associez à la vue table recevra des événements tels que scrollViewDidScroll: et vous pouvez appeler des méthodes telles que contentOffset sur la vue table pour rechercher la position de défilement.

 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]; 

Gentil et simple

Dans Swift vous pouvez faire quelque chose comme ça. La condition suivante sera vraie chaque fois que vous atteindrez la fin de la tableview

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

S’appuyant sur la réponse de @Jay Mayu, qui était selon moi l’une des meilleures solutions:

Objectif 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!") } } 

J’utilise généralement ceci pour charger plus de données, quand la dernière cellule commence à afficher

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

Prendre neoneye d’ excellentes réponses, mais rapidement et renommer les variables.

Fondamentalement, nous soaps que nous avons atteint le bas de la vue de la table si le yOffsetAtBottom dépasse la hauteur du contenu de la table.

 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 } 

Voici le code de version de 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 } } 

Ma solution consiste à append des cellules avant que la tableview décélère sur le décalage estimé. C’est prévisible sur la vélocité.

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

Mise à jour pour Swift 3

La réponse de Neoneye a fonctionné le mieux pour moi dans l’objective C, c’est l’équivalent de la réponse dans Swift 3:

 func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { 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") } } 

Je veux effectuer une action sur ma tableviewcell 1 pleine.

Le code est donc le lien suivant:

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

Puisse ceci aider quelqu'un.