10 Stimmen

SetNeedsDisplay funktioniert nicht

Ich habe viele Threads zu diesem Thema gesehen, aber keiner behandelt meinen Fall (denke ich).

Mein Fall sollte einfach sein. Ich habe eine benutzerdefinierte UIView in meinem Controller. Von meinem Controller aus verwende ich [self.myView setNeedsDisplay] und es funktioniert perfekt.

Ich habe Probleme, wenn ich versuche, dies von innerhalb der UIView selbst aufzurufen... Ich habe eine Benachrichtigung aus einer anderen Klasse gesendet, die von meiner Ansicht empfangen wird (das funktioniert) mit den übermittelten Informationen, ich aktualisiere interne Eigenschaften dieser Ansicht und dann rufe ich [self setNeedsDisplay] auf, in der Hoffnung, dass mein Bildschirm mit den neuen Zuständen aktualisiert wird, aber nichts passiert. Ich habe ein NSLog in meiner drawRect-Methode verwendet, und es wird zu diesem Zeitpunkt nicht aufgerufen. Es wird nur aufgerufen, wenn meine Controller-Klasse setNeedsDisplay aufruft, und wenn das passiert, wird die Aktualisierung, die zuvor hätte passieren sollen, auf dem Bildschirm angezeigt... Ich weiß nicht, warum es nicht vorher aktualisiert wird...

Hier sind einige Codezeilen:

Mein Controller fordert ein Update an: (funktioniert gut!)

- (void)addNodeToNetwork:(DTINode *)node
{
[self.myNetwork addNodeInTheNetwork:node];
self.gridView.nodesToDraw = [self.myNetwork.nodesInNetwork copy];

CGRect tempRec = CGRectMake(node.nodePosition.x, node.nodePosition.y node.nodePosition.x, node.nodePosition.y);
NSValue *rectObj = [NSValue valueWithCGRect:tempRec]; //transforma o cgrect num objeto

[self.gridView.fatherNodes setValue:rectObj forKey:node.nodeName];
[self.gridView setNeedsDisplay];
}

Meine Benachrichtigungsmethode versucht, meine Zeichnung zu aktualisieren: (funktioniert nicht!)

- (void) receiveTestNotification:(NSNotification *) notification
{
NSDictionary *userInfo = notification.userInfo;
DTINode *notificationNode = [userInfo objectForKey:@"myNode"];
NSLog("Ich bin hier!");
for (DTINode *node in self.nodesToDraw)
{
    NSLog("Auch hier");

    if(node.nodeName == notificationNode.fatherNode)
    {
        CGRect temp = CGRectMake(notificationNode.nodePosition.x, notificationNode.nodePosition.y, node.nodePosition.x, node.nodePosition.y);
        NSValue *tempObj = [NSValue valueWithCGRect:temp];
        [self.fatherNodes setObject:tempObj forKey:notificationNode.nodeName];
        [self setNeedsDisplay];
        NSLog("Sollte JETZT NEU GEZEICHNET werden!"); // Es druckt das, aber es wird nichts gezeichnet!
    }
}
}

Ich kopiere meinen drawRect nicht hierhin, weil er funktioniert. Das Problem ist, dass er nicht von UIView setNeedsDisplay aus aufgerufen wird!

Hat jemand eine Idee, warum das nicht funktioniert????

28voto

Plauto Abreu Punkte 449

Nach vielen Tests habe ich etwas im Zusammenhang mit Threads festgestellt und dass setNeedsDisplay nur im Hauptthread aufgerufen werden sollte... außerdem habe ich nie einen separaten Thread in diesen Klassen gestartet, die Klasse, die die Benachrichtigung ausgelöst hat, lief in einem sekundären Thread... und anscheinend war das das Problem...

Um es zu lösen, habe ich einfach setNeedsDisplay erzwungen, im Hauptthread aufgerufen zu werden..

dispatch_async(dispatch_get_main_queue(), ^{
            [self setNeedsDisplay];  
});

Swift 3:

DispatchQueue.main.async { [weak self] in
    self?.setNeedsDisplay()
}

0voto

Ronald Hofmann Punkte 1342

Ich denke, der richtige Weg, es zu benutzen, ist:

[self setNeedsDisplay:YES]; 

Obwohl ich immer Probleme habe, das zum Laufen zu bringen :(

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