27 Stimmen

Verzögertes Rendering von UIImageView in UITableView

Ok, ich habe eine UITableView mit benutzerdefinierten UITableViewCell s, die jeweils eine UIImageView deren Bilder asynchron über eine Schnittstelle heruntergeladen werden NSURLConnection . Alles ganz normales Zeug...

Das Problem besteht darin, dass die neuen Bilder beim Scrollen der Tabelle zwar korrekt im Hintergrund heruntergeladen, aber erst RENDERED werden, wenn sich die Tabelle nicht mehr bewegt.

Wie schaffe ich es, dass die Tabelle ihren Inhalt wiedergibt, auch wenn sie sich bewegt? Danke!

-- UPDATE --

Bei näherer Betrachtung stelle ich fest, dass die NSURLConnection Delegate-Methoden werden erst ausgelöst, wenn der Bildlauf der Tabelle beendet ist. Nicht sicher, warum. Jede Hilfe wäre großartig.

65voto

Daniel Dickison Punkte 21643

Der Grund dafür, dass die Nachrichten des Verbindungsdelegaten erst ausgelöst werden, wenn Sie mit dem Scrollen aufhören, ist, dass sich die Ausführungsschleife während des Scrollens in UITrackingRunLoopMode . Standardmäßig, NSURLConnection terminiert sich selbst in NSDefaultRunLoopMode nur, damit Sie beim Blättern keine Meldungen erhalten.

So planen Sie die Verbindung in den "üblichen" Modi, d. h. UITrackingRunLoopMode :

NSURLRequest *request = ...
NSURLConnection *connection = [[NSURLConnection alloc]
                               initWithRequest:request
                               delegate:self
                               startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
            forMode:NSRunLoopCommonModes];
[connection start];

Beachten Sie, dass Sie Folgendes angeben müssen startImmediately:NO i

1voto

benzado Punkte 78100

Sie sollten sich über NSRunLoop informieren. Ich vermute, dass während des Scrollens die Laufschleife im NSEventTrackingRunLoopMode läuft und die NSURLConnection nicht in diesem Modus enthalten ist. Sie könnten dies wahrscheinlich umgehen, indem Sie NSURLConnection's scheduleInRunLoop:forMode: aufrufen, so dass der Download während des Scrollens stattfinden kann.

Dies wird sich wahrscheinlich auf die Leistung des Bildlaufs auswirken, was wahrscheinlich der Grund für den separaten Laufschleifenmodus ist. Aber probieren Sie es aus und sehen Sie, wie es sich anfühlt!

1voto

ohhorob Punkte 11565

Wenn Sie das Herunterladen und Aktualisieren von Bildern in eine NSOperation verpacken, werden die Aktualisierungen beim Blättern in der Tabellenansicht durchgeführt.

Ein weiterer Vorteil von NSOperation ist, dass Sie die Operation abbrechen können, wenn die Zelle aus dem Bildschirm gleitet. Das ist für den Benutzer viel reaktionsfreudiger, vor allem, wenn er eine lange Liste schnell durchblättert. Der Apple Tech-Talk in diesem Jahr hat diese Technik gefördert.

Wenn Ihre Listen nicht so lang sind oder Sie es vorziehen, dass sie weiter geladen werden, können Sie stattdessen die Prioritäten der NSOperation ändern.

0voto

captain cosmic Punkte 33

Erstens: Ihre Verbindung wird wahrscheinlich nicht einmal gestartet, bis sie zur mainRunLoop gelangt, und dort wird auch die Bildlaufanimation verarbeitet.

Ich hatte das gleiche Problem und konnte es beheben, indem ich den Verbindungen für die Bilder mitteilte, dass sie sofort nach der Erstellung beginnen sollen.

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:wrapper.request delegate:wrapper];

    [connection start];

In der Abschlussroutine, in der Sie das Bild empfangen und cell.imageView.image auf das empfangene Bild setzen, sollten Sie prüfen, ob diese Zelle zu einer der Zellen gehört, die derzeit in der Tabelle angezeigt werden...und wenn ja, rufen Sie [tableView reloadData] auf.

    NSInteger itemIndex = theIndexInTheRowDataOfTheCellYouStuffedTheImage

    NSArray *indicies = [_tableView indexPathsForVisibleRows];
    NSUInteger rows = indicies.count;

    if (rows > 0 &&
        itemIndex >= ((NSIndexPath *)[indicies objectAtIndex:0]).row &&
        itemIndex <= ((NSIndexPath *)[indicies objectAtIndex:rows - 1]).row)
    {       
        [_tableView reloadData];
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X