2017-10-22 17 views
0

スウィフト4、MacOSの10.13回しNSImageViewそれは

スピン作る私はSO、まだNSImageViewではなく、そのの一つで、その中心で回転させることはできません上の回答の様々なを読みましたコーナー。

は今、画像はこの(ビデオ)のようになります。ここではhttp://d.pr/v/kwiuwS

は私のコードです:

//`loader` is an NSImageView on my storyboard positioned with auto layout 

loader.wantsLayer = true 

let oldFrame = loader.layer?.frame 
loader.layer?.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
loader.layer?.position = CGPoint(x: 0.5, y: 0.5) 
loader.layer?.frame = oldFrame! 

let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation") 
rotateAnimation.fromValue = 0.0 
rotateAnimation.toValue = CGFloat(-1 * .pi * 2.0) 
rotateAnimation.duration = 2 
rotateAnimation.repeatCount = .infinity 

loader.layer?.add(rotateAnimation, forKey: nil) 

すべてのアイデアは、私はまだ行方不明です何?

答えて

0

これは、ビューのレイヤーをデフォルトプロパティにリセットするレイアウトパスの結果です。たとえば、レイヤーのanchorPointを確認すると、0, 0にリセットされている可能性があります。

単純な解決策は、ビューコントローラーの場合は、viewDidLayout()に目的のレイヤプロパティを連続的に設定することです。基本的には、フレーム、アンカーポイント、および位置ダンスを、すべてのレイアウトパスで初期設定で行うことです。 をサブクラス化した場合、そのビュー内にそのロジックが含まれている可能性があります。これは、そのロジックを含むビューコントローラに入れるよりもはるかに良いでしょう。

updateLayerを使用して独自のNSViewサブクラスをバッキングレイヤーをオーバーライドするかロールオーバーする方が良い解決策がありますが、確かな答えを出すためにそこで実験しなければなりません。

1

すべてのビューで便利なsetAnchorPoint拡張を含むシンプルなデモを作成しました。

コーナーから回転が見える主な理由は、アンカーポイントがどうにかして0,0にリセットされることです。

import Cocoa 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 

@IBOutlet weak var window: NSWindow! 

func applicationDidFinishLaunching(_ aNotification: Notification) { 
    // Insert code here to initialize your application 

    // Create red NSImageView 
    let imageView = NSImageView(frame: NSRect(x: 100, y: 100, width: 100, height: 100)) 
    imageView.wantsLayer = true 
    imageView.layer?.backgroundColor = NSColor.red.cgColor 

    window.contentView?.addSubview(imageView) 

    // Before animate, reset the anchor point 
    imageView.setAnchorPoint(anchorPoint: CGPoint(x: 0.5, y: 0.5)) 
    // Start animation 
    if imageView.layer?.animationKeys()?.count == 0 || imageView.layer?.animationKeys() == nil { 
     let rotate = CABasicAnimation(keyPath: "transform.rotation") 
     rotate.fromValue = 0 
     rotate.toValue = CGFloat(-1 * .pi * 2.0) 
     rotate.duration = 2 
     rotate.repeatCount = Float.infinity 

     imageView.layer?.add(rotate, forKey: "rotation") 
    } 
} 

func applicationWillTerminate(_ aNotification: Notification) { 
    // Insert code here to tear down your application 
} 
} 

extension NSView { 
func setAnchorPoint(anchorPoint:CGPoint) { 
    if let layer = self.layer { 
     var newPoint = NSPoint(x: self.bounds.size.width * anchorPoint.x, y: self.bounds.size.height * anchorPoint.y) 
     var oldPoint = NSPoint(x: self.bounds.size.width * layer.anchorPoint.x, y: self.bounds.size.height * layer.anchorPoint.y) 

     newPoint = newPoint.applying(layer.affineTransform()) 
     oldPoint = oldPoint.applying(layer.affineTransform()) 

     var position = layer.position 

     position.x -= oldPoint.x 
     position.x += newPoint.x 

     position.y -= oldPoint.y 
     position.y += newPoint.y 

     layer.position = position 
     layer.anchorPoint = anchorPoint 
    } 
} 
} 

enter image description here

+0

あなたのコードは働いたが、この単純なアニメーションを作成するための簡単な方法は何ですか? – frank

+0

@frankそれはすでに簡単ではありませんか?既に拡張機能を与えたアンカーポイントとレイヤーの位置を設定し、単純なCABasicAnimationを実行します。 – brianLikeApple

+0

はい、拡張子はこれを簡単にします。 iOSでは、このアニメーションを作成するための追加作業は必要ありません。私は、このアニメーションをiOSのように簡単な方法があるのか​​分かりません。 – frank