在其中心旋转 NSImageView 使其旋转

Cli*_*rum 2 cocoa cabasicanimation nsimageview

斯威夫特 4,macOS 10.13

我已经阅读了关于 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)
Run Code Online (Sandbox Code Playgroud)

任何想法我仍然缺少什么?

bri*_*ple 9

我刚刚创建了一个简单的演示,其中包含setAnchorPoint所有视图的方便扩展。

您从角落看到旋转的主要原因是您的锚点以某种方式重置为 0,0。

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet weak var window: NSWindow!
var imageView: NSImageView!

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

    // Create red NSImageView
    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)
}

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

func applicationDidBecomeActive(_ notification: Notification) {
    // 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")
    }
}
}

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.anchorPoint = anchorPoint
        layer.position = position
    }
}
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • @Roee84我不确定......新版本只是将图像初始化代码和旋转代码分开,但仍然使用相同的扩展名。如果您初始化视图,有时即使您将其设置为 0.5,0.5,图层的锚点也会重置为 0,0。所以我们需要在整个布局确定之后使用扩展代码。 (2认同)