2016-06-21 81 views
0

我在drawRect中绘制了一个指南针拨号盘,我想避免重绘它,但是将它转换为标题指南针标题更改。当我使用CABasicAnimation这样的:旋转不带动画的自定义UIView

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"]; 

它旋转如预期(顶部和文字红色箭头是从指南针刻度盘不同的看法):

enter image description here

我真的不希望动画,所以我用的变体,如:

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

或者:

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

或者:

CATransform3D t = CATransform3DIdentity; 

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

他们都得出了相同的结果歪斜:

enter image description here

自动布局和约束不存在于这个观点。

我应该错过了一些东西,我不知道它是什么。我错过了什么以获得与动画相同的结果?

此外,从您的经验,我应该真的使用旋转转换有利于drawRect?在profiler中,我看到drawRect需要花费很多CPU周期。当我使用转换时,我没有看到“我的”cpu周期,但是当我密集旋转时,总CPU值几乎相同。

这将是伟大的驯服转换你的帮助:)!

回答

0

将我的头靠在墙上并查看视图上的.transform值后,我发现问题出在layoutSubviews中设置视图的框架中。当仅使用边界和中心时:

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

它正确地与问题中提到的所有转换选项一起工作。

原来,这是一个众所周知的事实,即如果在视图上设置了非标识转换(docs),则不应触摸框架。

但是,如果transform属性包含非标识转换,那么frame属性的值是未定义的,不应该修改。在这种情况下,您可以使用center属性重新定位视图,并使用bounds属性调整大小。

另外,请确保不要在其他地方使用变换视图的.frame。我在drawRect中将它用作.frame.size,当然必须将其更改为.bounds.size。