2016-06-21 23 views
0

Ich habe ein in drawRect gezeichnetes Kompassrad und möchte es nicht neu zeichnen, sondern es stattdessen drehen, wenn sich die Kompassrichtung ändert. Als ich CABasicAnimation wie folgt verwenden:Benutzerdefiniertes UIView ohne Animation

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
animation.fromValue = [NSNumber numberWithFloat:_dialAngle*M_PI/180]; 
animation.toValue = [NSNumber numberWithFloat:dialAngle*M_PI/180]; 
animation.duration = 0.0; 
animation.repeatCount = 0; 
animation.removedOnCompletion = false; 
animation.fillMode = kCAFillModeForwards; 
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
[dial.layer addAnimation:animation forKey:@"transform.rotation.z"]; 

es als (roter Pfeil oben und Text sind andere Ansicht vom Kompasses) erwartet dreht:

enter image description here

ich nicht wirklich wollen animieren, so habe ich Varianten wie:

[dial.layer setValue:[NSNumber numberWithDouble: dialAngle*M_PI/180] forKeyPath:@"transform.rotation.z"]; 

Oder:

dial.transform = CGAffineTransformMakeRotation(arrowAngle*M_PI/180); 

Oder:

CATransform3D t = CATransform3DIdentity; 

dial.layer.transform = CATransform3DRotate(t, dialAngle*M_PI/180, 0.0, 0.0, 1.0); 

Und sie führen alle zum gleichen Ergebnis verzerrt:

enter image description here

Automatische Anordnung und Einschränkungen sind auf dieser Ansicht nicht vorhanden.

Ich sollte etwas vermissen und ich kann uns nicht vorstellen, was es ist. Was fehlt mir, um das gleiche Ergebnis wie mit der Animation zu erhalten?

Auch, sollte ich aus Ihrer Erfahrung wirklich drehen Transformation für DrawRect verwenden? In Profiler sah ich, dass DrawRect einige CPU-Zyklen benötigte. Wenn ich Transformationen benutze, sehe ich nicht "meine" CPU-Zyklen, aber die Gesamt-CPU-Werte sind ungefähr gleich, wenn ich mich intensiv drehe.

Es wäre toll, die Transformationen mit Ihrer Hilfe zu zähmen :)!

Antwort

0

Nachdem ich meinen Kopf gegen die Wand geschlagen hatte und in die .transform-Werte auf der Ansicht schaute, fand ich heraus, dass das Problem darin bestand, .frame für die Ansicht in layoutSubviews zu setzen. Wenn nur Begrenzungen und Mitte verwendet werden:

dial.bounds = self.bounds; 
dial.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 

Es funktionierte korrekt mit allen in der Frage genannten Transformationsoptionen.

Es ist eine bekannte Tatsache, dass Sie den Frame nicht berühren sollten, wenn Sie eine nicht identitätsbasierte Transformation für eine Ansicht festgelegt haben (docs).

Wenn die Eigenschaft transform jedoch eine Transformation ohne Identität enthält, ist der Wert der Eigenschaft frame nicht definiert und sollte nicht geändert werden. In diesem Fall können Sie die Ansicht mit der Eigenschaft center neu positionieren und die Größe stattdessen mit der Eigenschaft bounds anpassen.

Stellen Sie sicher, dass Sie .frame der transformierten Ansicht nirgendwo anders verwenden. Ich benutzte es in drawRect als .frame.size und musste es natürlich in .bounds.size ändern.