wake-up-neo.com

Wie Sie wissen, wann UITableView im iPhone nach unten gescrollt wurde?

Ich würde gerne wissen, wann eine UITableView nach unten gescrollt wurde, um mehr Inhalt zu laden und anzuzeigen, etwa einen Delegierten oder etwas anderes, um den Controller wissen zu lassen, wann die Tabelle nach unten gelaufen ist.

Weiß jemand das, bitte helfen Sie mir, danke im Voraus! 

95
Son Nguyen

Am besten testen Sie einen Punkt am unteren Rand des Bildschirms und verwenden diesen Methodenaufruf, wenn der Benutzer einen Bildlauf ausführt (scrollViewDidScroll):

- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point

Testen Sie einen Punkt am unteren Rand des Bildschirms. Wenn Sie dann den Indexpfad verwenden, wird geprüft, ob der Indexpfad die letzte Zeile ist. Fügen Sie dann Zeilen hinzu.

17
Ajay

in der Tableview-Delegation tun Sie so etwas

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

Geänderte neoneyes antworten ein wenig.

Diese Antwort zielt auf diejenigen von Ihnen ab, die möchten, dass das Ereignis nur einmal ausgelöst wird pro Loslassen des Fingers.

Geeignet, wenn Sie mehr Inhalte von einem Inhaltsanbieter laden (Webservice, Kerndaten usw.). Beachten Sie, dass bei diesem Ansatz die Antwortzeit Ihres Webdienstes nicht berücksichtigt wird.

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

fügen Sie diese Methode in UITableViewDelegate hinzu:

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

Keine der obigen Antworten hat mir geholfen, also habe ich mir folgendes ausgedacht:

- (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
    }
}
19
Iftach Orr

Verwenden Sie – tableView:willDisplayCell:forRowAtIndexPath: (UITableViewDelegate Methode)

Vergleichen Sie einfach indexPath mit den Elementen in Ihrem Datenarray (oder mit der Datenquelle, die Sie für Ihre Tabellenansicht verwenden), um herauszufinden, ob das letzte Element angezeigt wird.

Dokumente: http://developer.Apple.com/library/ios/documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html#//Apple_ref/occ/intfm/UITableViewDelegate/tableView:willDisplayCell:forRowAtIndex :

19

UITableView ist eine Unterklasse von UIScrollView und UITableViewDelegate entspricht UIScrollViewDelegate. Der Delegat, den Sie an die Tabellenansicht anhängen, erhält Ereignisse wie scrollViewDidScroll:. Sie können Methoden wie contentOffset in der Tabellenansicht aufrufen, um die Bildlaufposition zu ermitteln.

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

Schön und einfach

8
user1641587

in Swift kannst du so etwas tun. Die folgende Bedingung ist immer dann erfüllt, wenn Sie das Ende der Tabellenansicht erreichen

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

Aufbauend auf @Jay Mayus Antwort, die meiner Meinung nach eine der besseren Lösungen war:

Ziel 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!")
    }
}
6
footyapps27

neoneye ausgezeichnete Antworten, aber in Swift, und Umbenennen der Variablen .. 

Grundsätzlich wissen wir, dass wir den unteren Rand der Tabellenansicht erreicht haben, wenn yOffsetAtBottom über der Tabelleninhaltshöhe liegt.

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
}
5
samwize

Im Allgemeinen verwende ich dies, um mehr Daten zu laden, wenn die Anzeige der letzten Zelle beginnt

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

Hier ist der Swift 3.0 Versionscode.

   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
        }
    }
5
Morshed Alam

Meine Lösung besteht darin, Zellen hinzuzufügen, bevor tableview um den geschätzten Offset verlangsamt wird. Es ist durch Geschwindigkeit vorhersagbar.

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

Update für Swift 3

Neoneyes Antwort hat in Objective C am besten funktioniert, dies entspricht der Antwort in 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")
    }
}
3
Ibrahim

Ich möchte eine Aktion für meine 1 vollständige Tableviewcell ausführen.

Der Code ist also der Link:

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

Möge dies jemandem helfen.

2

@neoneyes Antwort hat für mich funktioniert. Hier ist die Swift 4 Version davon

    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
    }
0
Anuran Barman