2 Stimmen

Ansicht wird nicht aktualisiert, aber alles im Hauptthread

Ich versuche, eine UIProgressView oben auf einer Tabellenansicht nach bestimmten Benutzerinteraktionen anzuzeigen. In meiner Tabellenansicht, wenn der Benutzer eine bestimmte Zelle tippt, schiebe ich eine UIView, die eine Symbolleiste mit Bar Elemente und eine Picker-Ansicht enthält (es verhält sich sehr viel wie ein Aktionsblatt). Wenn ich dies tue, füge ich die Ansicht außerhalb des Bildschirms zur aktuellen Ansicht hinzu und animiere dann das Einschieben. Wenn der Benutzer eine Auswahl trifft und auf "Fertig" tippt, wird die Ansicht wieder ausgeblendet. Zu diesem Zeitpunkt soll die Fortschrittsansicht erscheinen und aktualisiert werden, da einige Dinge im Hintergrund geschehen.

Das Problem, das ich habe, ist, dass nach der "alert sheet" UIView aus der aktuellen Ansicht geschoben wird, nichts passiert in der UI für eine gute Weile. Wenn ich die Schiebeansicht zeige, tue ich dies:

[[[UIApplication sharedApploication] keyWindow] addSubview:slidingView];
CGRect newFrame = CGRectMake(...);
[UIView animateWithDuration:0.3
    animations:^{
        slidingView.frame = newFrame;
    }];

Wenn der Benutzer in der Schiebeansicht auf die Schaltfläche "Fertig" tippt, wird diese Aktionsmethode aufgerufen:

- (void) done {
    NSNumber *row = GetSelectedRowSomehow();

    [self dismiss:@selector(doneCallback:) withObject:row];
}

- (void) dismiss:(SEL)cb withObject:(id)obj {
    [UIView animateWithDuration:0.3
        animations:^{
            slidingView.frame = CGRectMake(...);
        }
        completion:^(BOOL finished) {
            [self.delegate performSelectorOnMainThread:cb
                                            withObject:obj
                                         waitUntilDone:NO];
            [slidingView performSelectorOnMainThread:@selector(removeFromSuperview:)
                                          withObject:nil
                                       waitUntilDone:NO];
        }];
}

Der Callback, der hier aufgerufen wird:

- (void) doneCallback {
    self.dialogView.hidden = NO;
    self.progressView.progress = 0;

    for (float i = 0; i < 1.0; i += 0.1) {
        self.progressView.progress += i;
        sleep(0.5);
    }
}

In meinem Fall, dialogView erscheint erst nach callback abgeschlossen ist. Warum sollte die Anzeige nicht sofort nach der Fertigstellung aktualisiert werden? hidden Eigenschaft wurde festgelegt auf NO ?

2voto

JosephH Punkte 36576

Die Anzeige wird im Haupt-Thread aktualisiert, sobald die Ausführung Ihres Codes beendet ist. Wenn Sie den Haupt-Thread blockieren, verhindern Sie dies.

Ein Grund dafür ist, dass die Aktualisierungen gebündelt werden, damit sie effizient neu gezeichnet werden können.

Eine Lösung/Workaround wäre, performSelector:afterDelay:0.01 in doneCallback nach dem hidden=NO zu verwenden und den folgenden Code in einen neuen Selektor zu verschieben, der nach der Verzögerung läuft.

Alternativ könnten Sie den Code innerhalb von "doneCallback" als Hintergrundoperation ausführen (allerdings können Sie UIKit nicht direkt vom Hintergrund-Thread aus aktualisieren, so dass Sie Nachrichten an den Haupt-Thread für alle Anzeigeaktualisierungen senden müssten).

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