10

注意:これは、iOSではなくOSX上のCocoaアプリ用です。

レイヤーでバックアップされたNSButton(NSViewのサブクラス)があります。私がやりたいのは、CoreAnimationを使用してそのボタンを回転させることです。私はそれを行うために次のコードを使用しています:

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)の左下隅)になることを除いて機能します。次に、レイヤーはその中心を中心に回転しますが、明らかに左下隅へのジャンプは受け入れられません。

したがって、よく読んだ後、1​​0.8APIリリースノートでこの行を見つけました。

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でそのようなメソッドを見つけることができません)。一日の終わりに、ボタンを中心点を中心に無期限に回転させたいだけです。

4

2 に答える 2

18

NSViewの直接の「カバー」であるメソッドは見当たりませんanchorPoint

あなたが引用したものに加えて、10.8リリースノートで私が見ているのはこれです:

また、アンカーポイントは常に (0,0)、…に設定されます。</p>

は、スーパーレイヤーの座標系で レイヤーのanchorPointどのポイントにあるかを制御します。(0,0) に設定します。これは、レイヤーの左下隅が であることを意味します。positionNSViewself.layer.anchorPointself.layer.position

(0.5,0.5) に設定anchorPointすると、レイヤーの中心がレイヤーのposition. を変更していないのでposition、ご覧のようにレイヤーを左下に移動する効果があります。

position次のように、レイヤーanchorPointが (0.5,0.5) のときに必要な を計算する必要があります。

CGRect frame = _refreshButton.layer.frame;
CGPoint center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
_refreshButton.layer.position = center;
_refreshButton.layer.anchorPoint = CGPointMake(0.5, 0.5);
于 2013-02-12T21:28:11.923 に答える
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")
于 2020-07-20T08:57:33.513 に答える