[UITableView scrollToRowAtIndexPath:atScrollPosition:animated] blättert nicht nach ganz unten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • [UITableView scrollToRowAtIndexPath:atScrollPosition:animated] blättert nicht nach ganz unten

    Hallo zusammen!

    Heute wieder ein klassischer Fall für "WTF!" ... hier gepostet als psychotherapeutische Maßnahme, um dem ein oder anderen das Suchen zu ersparen und mit der Hoffnung auf eine gute Erklärung:

    Ich nutze in iOS-Apps UITableViews zum Anlisten / Auswählen verschiedener Optionen, wie zum Beispiel Farben, wobei die jeweils gewählte Option mit einem Checkmark markiert wird:

    Simulator Screen Shot - iPhone 8 Plus - 2018-03-26 at 18.46.36.png

    Ausserdem wird im viewWillAppear: des ViewControllers an die entsprechende Zeile (-1) gescrollt, damit der Benutzer die aktuelle Auswahl direkt im Blick hat.

    Vor einiger Zeit fiel mir auf, dass bei diesem Blättern nicht mehr auf exakte Zeilen positioniert wird ... Naja, sagen wir einmal, jetzt im Nachhinein fällt es mir wieder ein. Am Wochenende habe ich nämlich an einer neuen Version der App geschrieben und beim Testen merkte ich, dass nicht genügend nach unten geblättert wird, wenn die letzte Zeile ausgewählt war. Hey, das hat mal funktioniert! :cursing:

    Mit etwas Google-fu habe ich dann festgestellt, dass (1.) ich nicht alleine bin - das ist schon mal gut - und dass (2.) es eine "Lösung" gibt ... naja, eher eine Variante, bei der dieser Effekt nicht auftritt: Man packe den Methodenaufruf zum Scrollen in eine dispatch-Block in der Main-Queue:

    C-Quellcode

    1. NSIndexPath *colorIndex = [NSIndexPath indexPathForRow:MAX(0, [self indexOfThread] - 1) inSection:0];
    2. dispatch_async(dispatch_get_main_queue(),
    3. ^{
    4. // Dirty hack to have the tableview properly scrolling to the last row (e.g. https://stackoverflow.com/questions/12514770/ios-uitableview-scrolltorowatindexpath-not-working-anymore/12526636)
    5. [self.tableView scrollToRowAtIndexPath:colorIndex atScrollPosition:UITableViewScrollPositionTop animated:NO];
    6. });
    Nicht, dass wir uns mißverstehen: Vorher (ohne "dispatch_asynch") wurde die Methode auch in der Main-Loop (im viewWillAppear: des ViewControllers) aufgerufen.

    Ich vermute, dass die Ausführung des o. g. Blocks zu einer leichten Verzögerung führt, nach der die Tableview ausreichend initiiert ist, das Blättern korrekt durchführen zu können. Ich kann nicht genau sagen, ab welcher iOS-Version der Fehler auftrat, es könnte aber mit Einführung variabler Zeilenhöhen o. ä. sein. Wie gesagt, nur Vermutungen und ich würde mich sehr über einen guten Erklärungsversuch von Euch freuen.

    Und ja, dieses Projekt bereitet mir viel Freude: Statt einer "einfachen" Umstellung einer App auf den UISplitViewController und etwas Code-Cleaning schlage ich mich (gefühlt) laufend mit irgendwelchen Effekten herum, die eigentlich gar nicht auftreten dürften...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Das Problem könnte am Layout liegen, sprich der TableView hat im viewWillAppear: evtl. noch nicht die korrekte Größe/Höhe.

    Gibt mal den Frame vom UITableView per NSLog in viewWillAppear: und viewDidAppear: aus.

    Dann teste mal, ob das Problem auch auftritt, wenn Du den Aufruf von scrollToRowAtIndexPath:atScrollPosition:animated: in viewDidAppear: ausführst.
  • MCDan schrieb:

    Das Problem könnte am Layout liegen, sprich der TableView hat im viewWillAppear: evtl. noch nicht die korrekte Größe/Höhe.

    Gibt mal den Frame vom UITableView per NSLog in viewWillAppear: und viewDidAppear: aus.

    Dann teste mal, ob das Problem auch auftritt, wenn Du den Aufruf von scrollToRowAtIndexPath:atScrollPosition:animated: in viewDidAppear: ausführst.
    Das Frame bleibt konstant, allerdings ändern sich die Bounds, ich vermute mal, aufgrund der Navigationbar:

    Quellcode

    1. [STBPaletteController viewWillAppear:] [Line 83] frame: {{0, 0}, {414, 736}}
    2. [STBPaletteController viewWillAppear:] [Line 84] bounds: {{0, 0}, {414, 736}}
    3. [STBPaletteController viewDidAppear:] [Line 101] frame: {{0, 0}, {414, 736}}
    4. [STBPaletteController viewDidAppear:] [Line 102] bounds: {{0, -64}, {414, 736}}
    Der Wechsel in viewDidAppear:animated: behebt den Effekt ebenfalls ... das spricht für die Annahme, ein unfertiges Layout wäre der Verursacher. Allerdings kommt es zu einem sichtbarem Wechsel in der Scroll-Position bei Aufruf der View. Schade, denn nun bleibt mir die Wahl zwischen einem Hack, der mir fishy erscheint, und einer Anzeige, die sich unrund anfühlt... Ich habe mich noch nicht entscheiden.

    Danke :)

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.