我有一个用drawRect绘制的指南针刻度盘,我想避免重绘它,但是当箭头标题改变时,将其旋转。当我像这样使用CABasicAnimation:
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"];
它按预期旋转(顶部的红色箭头和文本是罗盘刻度盘的不同视图):
我真的不想动画,所以我使用的变体如:
[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);
他们都导致了同样的结果:
此视图中不存在Autolayout和约束。
我应该遗漏一些东西而且我无法弄明白它是什么。为了获得与动画相同的结果,我缺少什么?
另外,根据您的经验,我是否应该使用旋转变换来支持drawRect?在profiler中,我看到drawRect占用了不少cpu周期。当我使用变换时,我没有看到“我的”cpu周期,但是当我进行密集旋转时,总CPU值几乎相同。
在你的帮助下驯服变形会很棒!)!
答案 0 :(得分:0)
将我的头撞到墙上并查看视图上的.transform值后,我发现问题出在layoutSubviews中为视图设置.frame。仅使用边界和中心时:
dial.bounds = self.bounds;
dial.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
它可以正确使用问题中提到的所有转换选项。
事实证明,如果您在视图上设置了非标识转换(docs),则不应触摸该帧。
但是,如果transform属性包含非标识变换,则frame属性的值是未定义的,不应修改。在这种情况下,您可以使用center属性重新定位视图,并使用bounds属性调整大小。
另外请确保不要在其他任何地方使用转换后视图的.frame。我在drawRect中使用它作为.frame.size,当然必须将其更改为.bounds.size。