【问题标题】:Core Animation: set anchorPoint on 10.8 to rotate a layer about its center核心动画:将 anchorPoint 设置为 10.8 以围绕其中心旋转图层
【发布时间】:2013-01-28 03:50:16
【问题描述】:

注意:这是针对 OS X 上的 Cocoa 应用程序,而不是 iOS。

我有一个层支持的 NSButton(NSView 的子类)。我想要做的是使用核心动画旋转那个按钮。我正在使用以下代码来做到这一点:

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)。

我的问题是:我该如何解决这个问题?为图层设置anchorPoint的“适当的NSView覆盖方法”是什么(我在NSView上找不到这样的方法)。归根结底,我只想让我的按钮无限期地围绕其中心点旋转。

【问题讨论】:

    标签: objective-c macos cocoa core-animation core-graphics


    【解决方案1】:

    我遇到了与 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")
    

    【讨论】:

      【解决方案2】:

      我在NSView 上没有看到任何直接“覆盖”anchorPoint 的方法。

      我在the 10.8 release notes 看到的,除了你引用的,是这样的:

      anchorPoint 也总是设置为 (0,0),...

      anchorPoint 控制图层的哪个点位于超图层坐标系中的positionNSViewself.layer.anchorPoint 设置为 (0,0),这意味着图层的左下角位于 self.layer.position

      当您将anchorPoint 设置为 (0.5,0.5) 时,这意味着图层的中心应位于图层的position。由于您没有修改position,因此正如您所见,这具有将图层向下和向左移动的效果。

      anchorPoint 为 (0.5,0.5) 时,您需要计算您希望该层具有的position,如下所示:

      CGRect frame = _refreshButton.layer.frame;
      CGPoint center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
      _refreshButton.layer.position = center;
      _refreshButton.layer.anchorPoint = CGPointMake(0.5, 0.5);
      

      【讨论】:

      • 完美!你懂的;我看到了 position 属性,但没有尝试,因为我阅读了上面的注释,上面说 AppKit 将控制它。感谢您的解决方案!
      • 知道为什么旋转 M_PI/2 第一次会逆时针旋转,然后会顺时针旋转吗?
      • 我必须看看你的代码。您应该发布自己的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 1970-01-01
      相关资源
      最近更新 更多