Ich habe eine Ebene mit komplexem Zeichnungscode in der Methode -drawInContext :. Ich versuche, den Zeichnungsaufwand zu minimieren, daher verwende ich -setNeedsDisplayInRect:, um nur die geänderten Teile zu aktualisieren. Das funktioniert hervorragend. Wenn das Grafiksystem jedoch meine Ebene aktualisiert, wechselt es mithilfe einer Überblendung vom alten zum neuen Bild. Ich möchte, dass es sofort umschaltet.
Ich habe versucht, mit CATransaction Aktionen auszuschalten und die Dauer auf Null zu setzen, und beides funktioniert nicht. Hier ist der Code, den ich verwende:
[CATransaction begin];
[CATransaction setDisableActions: YES];
[self setNeedsDisplayInRect: rect];
[CATransaction commit];
Gibt es eine andere Methode für CATransaction, die ich stattdessen verwenden sollte (ich habe auch versucht -setValue: forKey: mit kCATransactionDisableActions das gleiche Ergebnis).
quelle
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });
Antworten:
Sie können dies tun, indem Sie das Aktionswörterbuch auf der zurückzugebenden Ebene festlegen
[NSNull null]
als Animation für die entsprechende Taste zurückgegeben wird. Zum Beispiel benutze ichDeaktivieren von Ein- / Ausblendanimationen beim Einfügen oder Ändern von Unterebenen in einer meiner Ebenen sowie von Änderungen der Größe und des Inhalts der Ebene. Ich glaube, der
contents
Schlüssel ist der, nach dem Sie suchen, um das Überblenden bei aktualisierten Zeichnungen zu verhindern.Schnelle Version:
quelle
@"position"
Taste, um eine Bewegung beim Wechseln des Rahmens zu verhindern .@"hidden"
Eigenschaft auch im Aktionswörterbuch hinzufügen, wenn Sie die Sichtbarkeit einer Ebene auf diese Weise umschalten und die Deckkraftanimation deaktivieren möchten.actionForKey:
statt), die EntdeckungfontSize
,contents
,onLayout
undbounds
. Es scheint, als könnten Sie jeden Schlüssel angeben, den Sie in dersetValue:forKey:
Methode verwenden könnten , und tatsächlich komplexe Schlüsselpfade wie angebenbounds.size
.Ebenfalls:
quelle
//foo
mit[self setNeedsDisplayInRect: rect]; [self displayIfNeeded];
der ursprünglichen Frage zu beantworten.[CATransaction setDisableActions:YES]
[CATransaction setDisableActions:YES]
ist eine Abkürzung für nur die[CATransaction setValue:forKey:]
Zeile. Sie brauchen noch diebegin
undcommit
Zeilen.Wenn Sie die Eigenschaft eines Layers ändern, erstellt CA normalerweise ein implizites Transaktionsobjekt, um die Änderung zu animieren. Wenn Sie die Änderung nicht animieren möchten, können Sie implizite Animationen deaktivieren, indem Sie eine explizite Transaktion erstellen und die Eigenschaft kCATransactionDisableActions auf true setzen .
Ziel c
Schnell
quelle
Zusätzlich zu Brad Larsons Antwort : Für benutzerdefinierte Ebenen (die von Ihnen erstellt wurden) können Sie die Delegierung verwenden, anstatt die Ebenen zu ändern
actions
Wörterbuch ändern. Dieser Ansatz ist dynamischer und kann performanter sein. Außerdem können alle impliziten Animationen deaktiviert werden, ohne dass alle animierbaren Schlüssel aufgelistet werden müssen.Leider ist es nicht möglich,
UIView
s als benutzerdefinierte Layer-Delegaten zu verwenden, da jederUIView
bereits ein Delegat seiner eigenen Ebene ist. Sie können jedoch eine einfache Hilfsklasse wie diese verwenden:Verwendung (innerhalb der Ansicht):
Manchmal ist es praktisch, den Controller von view als Delegaten für die benutzerdefinierten Unterschichten von view zu haben. In diesem Fall ist keine Hilfsklasse erforderlich. Sie können die
actionForLayer:forKey:
Methode direkt im Controller implementieren .Wichtiger Hinweis: Versuchen Sie nicht, den Delegaten der
UIView
zugrunde liegenden Ebene zu ändern (z. B. um implizite Animationen zu aktivieren) - es werden schlimme Dinge passieren :)Hinweis: Wenn Sie Ebenen- Neuzeichnungen animieren (nicht deaktivieren) möchten, ist es sinnlos, einen
[CALayer setNeedsDisplayInRect:]
Aufruf in eine zu setzenCATransaction
, da das tatsächliche Neuzeichnen manchmal (und wahrscheinlich auch später) erfolgen kann. Der gute Ansatz besteht darin, benutzerdefinierte Eigenschaften zu verwenden, wie in dieser Antwort beschrieben .quelle
CALayer
, dass es nichtnoImplicitAnimations
funktioniert hat. Vielleicht sollten Sie Ihre eigene Antwort als richtig markieren und erklären, was mit dieser Ebene nicht stimmte?CALayer
Instanz getestet (ich hatte damals zwei).NSNull
implementiert dasCAAction
Protokoll nicht und dies ist kein Protokoll, das nur optionale Methoden hat. Auch dieser Code stürzt ab und man kann ihn nicht einmal schnell übersetzen. Bessere Lösung: Passen Sie Ihr Objekt an dasCAAction
Protokoll an (mit einer leerenrunActionForKey:object:arguments:
Methode, die nichts bewirkt) und kehren Sieself
stattdessen zurück[NSNull null]
. Gleicher Effekt, aber sicher (wird nicht sicher abstürzen) und funktioniert auch in Swift.Hier ist eine effizientere Lösung, ähnlich der akzeptierten Antwort, jedoch für Swift . In einigen Fällen ist es besser, als jedes Mal eine Transaktion zu erstellen, wenn Sie den Wert ändern, was ein Leistungsproblem darstellt, wie andere bereits erwähnt haben, z. B. den allgemeinen Anwendungsfall, die Ebenenposition mit 60 fps zu verschieben.
Siehe Apple - Dokumentation für wie Schicht Maßnahmen gelöst werden . Das Implementieren des Delegaten würde eine weitere Ebene in der Kaskade überspringen, aber in meinem Fall war dies zu chaotisch, da der Delegat auf die zugehörige UIView eingestellt werden musste .
Bearbeiten: Aktualisiert dank des Kommentators, der darauf hinweist, dass dies
NSNull
konform istCAAction
.quelle
NullAction
für Swift zu erstellen ,NSNull
entsprichtCAAction
bereits, so dass Sie dasselbe tun können, was Sie in Ziel C tun: layer.actions = ["position": NSNull ()]Basierend auf Sams Antwort und Simons Schwierigkeiten ... fügen Sie die Delegatenreferenz nach dem Erstellen des CSShapeLayer hinzu:
... an anderer Stelle in der "m" -Datei ...
Im Wesentlichen dasselbe wie bei Sam ohne die Möglichkeit, über die benutzerdefinierte Variablenanordnung "disableImplicitAnimations" umzuschalten. Eher ein "Hard-Wire" -Ansatz.
quelle
Eigentlich fand ich keine der Antworten richtig. Die Methode, die das Problem für mich löst, war folgende:
Dann können Sie jede Logik darin verwenden, um eine bestimmte Animation zu deaktivieren, aber da ich sie alle entfernen wollte, gab ich null zurück.
quelle
So deaktivieren Sie implizite Ebenenanimationen in Swift
quelle
disableActions()
da es so klingt, als ob es dasselbe tut, aber es ist tatsächlich, um den aktuellen Wert zu erhalten. Ich denke, es ist auch markiert@discardable
, was es schwieriger macht, dies zu erkennen. Quelle: developer.apple.com/documentation/quartzcore/catransaction/…Es wurde eine einfachere Methode zum Deaktivieren der Aktion in einem System gefunden
CATransaction
, die internsetValue:forKey:
denkCATransactionDisableActions
Schlüssel anfordert:Schnell:
quelle
Fügen Sie dies Ihrer benutzerdefinierten Klasse hinzu, in der Sie die Methode -drawRect () implementieren. Nehmen Sie Änderungen am Code vor, um Ihren Anforderungen zu entsprechen. Für mich hat 'Opazität' den Trick getan, um Cross-Fade-Animationen zu stoppen.
quelle
Wenn Sie jemals eine sehr schnelle (aber zugegebenermaßen hackige) Lösung benötigen, lohnt es sich möglicherweise, nur (Swift) zu tun:
quelle
view.layer?.actions = [:]
die nicht wirklich funktioniert. Das Einstellen der Geschwindigkeit ist hässlich, funktioniert aber.Aktualisiert für schnelles und Deaktivieren nur einer impliziten Eigenschaftsanimation unter iOS und nicht unter MacOS
Ein weiteres Beispiel: In diesem Fall werden zwei implizite Animationen entfernt.
quelle
Ab iOS 7 gibt es eine praktische Methode, die genau dies tut:
quelle
So deaktivieren Sie die nervige (verschwommene) Animation beim Ändern der Zeichenfolgeeigenschaft eines CATextLayer:
und verwenden Sie es dann wie folgt (vergessen Sie nicht, Ihren CATextLayer ordnungsgemäß einzurichten, z. B. die richtige Schriftart usw.):
Sie können mein komplettes Setup von CATextLayer hier sehen:
Jetzt können Sie caTextLayer.string so oft aktualisieren, wie Sie möchten =)
Inspiriert von dieser und dieser Antwort.
quelle
Versuche dies.
Warnung
Wenn Sie den Delegaten der UITableView-Instanz festlegen, kommt es manchmal zu einem Absturz.
quelle