2010-12-04 14 views
30

Animieren Dies ist ein Follow-up zu How to get notified when a tableViewController finishes animating the push onto a nav stack.Wie benachrichtigt werden, wenn scrollToRowAtIndexPath beendet

In einem tableView ich eine Zeile mit Animation deaktivieren will, aber erst nach dem Tableview hat beendet das Buch zu dem ausgewählten Animieren Reihe. Wie kann ich benachrichtigt werden, wenn das passiert oder welche Methode in dem Moment aufgerufen wird, in dem sie beendet wird?

Dies ist die Ordnung der Dinge:

  1. Push-View-Controller
  2. In viewWillAppear ich eine bestimmte Zeile auswählen.
  3. In viewDidAppear I scrollToRowAtIndexPath (in die ausgewählte Zeile).
  4. Dann, wenn das Scrollen beendet ich deselectRowAtIndexPath: animated:YES wollen

Auf diese Weise wird der Benutzer wissen, warum sie dort gescrollt wurden, aber dann kann ich die Auswahl abklingen.
Schritt 4 ist der Teil, den ich noch nicht herausgefunden habe. Wenn ich es in viewDidAppear anrufe, ist die Zeile bereits zu dem Zeitpunkt, zu dem die TableView scrollt, bereits abgewählt, was nicht gut ist.

Antwort

56

Sie können die Methode scrollViewDidEndScrollingAnimation: des Delegaten für die Tabellenansicht verwenden. Dies liegt daran, dass UITableView eine Unterklasse von UIScrollView und UITableViewDelegate konform zu UIScrollViewDelegate ist. Mit anderen Worten, eine Tabellenansicht ist eine Bildlaufansicht und ein Tabellenansichtsdelegat ist auch ein Bildlaufdelegat.

Erstellen Sie also eine scrollViewDidEndScrollingAnimation:-Methode in Ihrem Tabellenansichtsdelegaten und deaktivieren Sie die Zelle in dieser Methode. Informationen zur scrollViewDidEndScrollingAnimation:-Methode finden Sie in der Referenzdokumentation für UIScrollViewDelegate.

+0

Nochmals vielen Dank! – Andrew

+0

Gern geschehen. –

+41

Es wäre schön, wenn iOS eine Version mit Vervollständigungsblock bietet (wie 'UIView animateWithDuration: Animationen: Vervollständigung'), sodass die Benachrichtigung kontextspezifisch sein kann ... – pixelfreak

11

Um Ben Packards Kommentar zu der akzeptierten Antwort zu adressieren, können Sie dies tun. Testen Sie, ob die TableView zur neuen Position blättern kann. Wenn nicht, führen Sie Ihre Methode sofort aus. Wenn es scrollen kann, warten Sie, bis das Scrollen beendet ist, um Ihre Methode auszuführen.

- (void)someMethod 
{ 
    CGFloat originalOffset = self.tableView.contentOffset.y; 
    [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; 
    CGFloat offset = self.tableView.contentOffset.y; 

    if (originalOffset == offset) 
    { 
     // scroll animation not required because it's already scrolled exactly there 
     [self doThingAfterAnimation]; 
    } 
    else 
    { 
     // We know it will scroll to a new position 
     // Return to originalOffset. animated:NO is important 
     [self.tableView setContentOffset:CGPointMake(0, originalOffset) animated:NO]; 
     // Do the scroll with animation so `scrollViewDidEndScrollingAnimation:` will execute 
     [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; 
    } 
} 

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 
{ 
    [self doThingAfterAnimation]; 
} 
+1

Wie wäre es mit '[self.tableView.indexPathsForVisibleRows enthältObjekt: Pfad]'? – Pim

+2

Es ist wahr, wenn indexPath * nicht * sichtbar ist, muss es auf jeden Fall gescrollt werden, um korrekt positioniert zu werden, so dass Sie in diesem Fall das 'contentOffset'-Fiedeln überspringen können. Wenn der IndexPfad ** jedoch ** sichtbar ist, kann die TableView möglicherweise nicht in der Lage sein, sie in die Position zu scrollen. Daher sollten Sie die contentOffsets überprüfen (wie oben gezeigt). – EthanB

8

Sie können die scrollToRowAtIndexPath: innerhalb eines [UIView animateWithDuration:...] Block enthalten, die den Abschluss Block auslösen wird schließlich schließen Animationen enthalten. So etwas wie folgt aus:

[UIView 
    animateWithDuration:0.3f 
    delay:0.0f 
    options:UIViewAnimationOptionAllowUserInteraction 
    animations:^ 
    { 
     // Scroll to row with animation 
     [self.tableView scrollToRowAtIndexPath:indexPath 
          atScrollPosition:UITableViewScrollPositionTop 
            animated:YES]; 
    } 
    completion:^(BOOL finished) 
    { 
     // Deselect row 
     [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    }]; 
+0

Clever :) Obwohl das die Standardanimationsdauer für den ScrollToRowAtIndexPath überschreibt? – BastiBen

+0

korrekt, überschreibt es die Standarddauer, aber abhängig von dem Wert, den Sie festgelegt haben, könnte Ihre App deutlich/eindeutig (was eine gute Sache sein könnte) oder Sie könnten einen Wert so nahe an der Vorgabe, dass es fast wird für Ihre Benutzer nicht wahrnehmbar. –

+0

Gute Antwort - aber der 'animierte' Parameter von' scrollToRowAtIndexPath' sollte auf NEIN gesetzt werden - er befindet sich bereits im Animationsblock. –

28

versuchen diese

[UIView animateWithDuration:0.3 animations:^{ 
    [yourTableView scrollToRowAtIndexPath:indexPath 
         atScrollPosition:UITableViewScrollPositionTop 
           animated:NO]; 
} completion:^(BOOL finished){ 
    //do something 
}]; 

nicht auf NO, die Animation von scrollToRow animiert Set Vergessen wird von UIView animateWithDuration außer Kraft gesetzt werden.

Hoffe diese Hilfe!

+1

Ich konnte aufgrund dieses Vorschlags tun, was ich wollte, also nehme ich an, dass ich dir einen besitze :) – alasker

+0

ACHTUNG MIT DIESER LÖSUNG: Ich benutzte diese Methode eine Weile, bis ich merkwürdiges Verhalten in Zellen sah, zu denen gescrollt wurde . Bilder, die versteckt waren, wurden angezeigt ... unerklärlich. Das Debugging würde anzeigen, dass sie nicht sichtbar waren. Aber sie waren, wenn sie auf einem Gerät laufen. Ich isolierte das Problem auf den scrollToRowAtIndexPath mit animierter Menge auf Nein innerhalb des Animationsblocks. Verschiebe es außerhalb des Animationsblocks und ohne Probleme. Aber dann keine Animation ... Diese Technik kann also Probleme verursachen. Ich habe aktualisiert, um James Huddlestons scrollViewDidEndScrollingAnimation-Lösung zu verwenden, um das Problem zu beheben. –

0

Implementierung in einer Swift-Erweiterung.

Dies funktioniert in den meisten Fällen, obwohl der TableView-Delegat während des Bildlaufs geändert wird, was in einigen Fällen unerwünscht sein kann.

Verwandte Themen