注意:这适用于OS X上的Cocoa应用,而非iOS。
我有一个支持图层的NSButton(NSView的子类)。我想要做的是使用Core Animation旋转该按钮。我正在使用以下代码来执行此操作:
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
a.fromValue = [NSNumber numberWithFloat:0];
a.toValue = [NSNumber numberWithFloat:-M_PI*2];
[_refreshButton.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
a.duration = 1.8; // seconds
a.repeatCount = HUGE_VAL;
[_refreshButton.layer addAnimation:a forKey:nil];
这是有效的,除了它运行时,图层向下跳到左边,使其中心点位于NSView的原点,即(0,0)的左下角。然后该层围绕其中心旋转,但显然跳到左下角是不可接受的。
因此,经过多次阅读,我在10.8 API发行说明中找到了这一行:
On 10.8, AppKit will control the following properties on a CALayer
(both when "layer-hosted" or "layer-backed"): geometryFlipped, bounds,
frame (implied), position, anchorPoint, transform, shadow*, hidden,
filters, and compositingFilter. Use the appropriate NSView cover methods
to change these properties.
这意味着AppKit在上面的代码中“忽略”我对-setAnchorPoint的调用,而是将该锚点设置为NSView的原点(0,0)。
我的问题是:我该如何解决这个问题?什么是“适当的NSView封面方法”来设置图层的anchorPoint(我在NSView上找不到这样的方法)。在一天结束时,我只是希望我的按钮无限期地围绕其中心点旋转。
答案 0 :(得分:16)
我认为NSView
上的任何方法都不是anchorPoint
的直接“封面”。
除了你引用的内容之外,我在the 10.8 release notes中看到的是:
anchorPoint也始终设置为(0,0),...
anchorPoint
控制图层的哪个点位于超层坐标系中的position
。 NSView
将self.layer.anchorPoint
设置为(0,0),这意味着图层的左下角位于self.layer.position
。
当您将anchorPoint
设置为(0.5,0.5)时,这意味着图层的中心应位于图层的position
。由于您没有修改position
,因此您可以将图层向下和向左移动,如您所见。
您需要计算图层在其position
为(0.5,0.5)时所拥有的anchorPoint
,如下所示:
CGRect frame = _refreshButton.layer.frame;
CGPoint center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
_refreshButton.layer.position = center;
_refreshButton.layer.anchorPoint = CGPointMake(0.5, 0.5);
答案 1 :(得分:0)
我在Swift中遇到了与@Bryan完全相同的问题:在动画过程中,该对象将跳离其原始位置。这是适用于macOS的NSButton的代码:
let frame : CGRect = startButton.layer!.frame
let center : CGPoint = CGPoint(x: frame.midX, y: frame.midY)
startButton.layer?.position = center;
startButton.layer?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
let pulse = CASpringAnimation(keyPath: "transform.scale")
pulse.duration = 0.2
pulse.fromValue = 0.95
pulse.toValue = 1.0
pulse.autoreverses = true
pulse.repeatCount = 10
pulse.initialVelocity = 0.5
pulse.damping = 1.0
startButton.layer?.add(pulse, forKey: "pulse")