【问题标题】:How to prevent an NSImageView from loosing an animation when its parent NSToolbar is hidden/shown?如何防止 NSImageView 在其父 NSToolbar 隐藏/显示时丢失动画?
【发布时间】:2018-03-07 04:22:18
【问题描述】:

Xcode: 9.2.
ma​​cOS 目标: 10.13

当父 NSToolbar 隐藏然后随后显示时,NSImageView 似乎会丢失添加到其层的任何动画。

有没有办法指示 AppKit 放手/恢复动画状态?

示例代码

class WindowController: NSWindowController, CALayerDelegate {

static let spinAnimation: CAAnimation = {
    let basicAnimation = CABasicAnimation(keyPath:"transform.rotation")
    basicAnimation.fromValue = 2.0 * .pi
    basicAnimation.toValue = 0.0
    basicAnimation.duration = 1.0
    basicAnimation.repeatCount = Float.infinity

    return basicAnimation
}()

@IBOutlet weak var imageView: NSImageView! {
    didSet{
        let layer = CALayer()
        layer.contentsScale = 2.0
        layer.contentsGravity = "aspectFit"
        layer.contents = #imageLiteral(resourceName: "windmill")
        imageView.layer = layer
        imageView.wantsLayer = true
        imageView.layerContentsRedrawPolicy = .onSetNeedsDisplay
        imageView.layer?.delegate = self
        imageView.needsDisplay = true
    }
}

func display(_ layer: CALayer) {
    let frame = layer.frame
    layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    layer.frame = frame
}

override func windowDidLoad() {
    super.windowDidLoad()


    let key = "spinAnimation"

    self.imageView.layer?.add(WindowController.spinAnimation, forKey: key)

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(5)) {
        self.imageView.layer?.removeAnimation(forKey: key)
    }
}
}

Sample Xcode project on GitHub

【问题讨论】:

    标签: swift macos core-animation appkit


    【解决方案1】:

    通常,当动画的层从屏幕上的层树中移除时,动画被视为“完成”。默认情况下,当动画完成时,动画会从其图层中移除。 AppKit 从窗口中移除了工具栏视图(以及它的所有子视图及其层),因此动画被认为已完成并从其层中移除。

    要保持动画安装,您可以将动画的isRemovedOnCompletion 设置为false。

    import Cocoa
    
    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate {
    
        @IBOutlet weak var window: NSWindow!
        @IBOutlet var customItem: NSToolbarItem!
    
        func applicationDidFinishLaunching(_ aNotification: Notification) {
            let view = customItem.view!
            view.wantsLayer = true
            let layer = view.layer!
            let frame = layer.frame
            layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
            layer.frame = frame
    
            let animation = CABasicAnimation(keyPath: "transform.rotation")
            animation.fromValue = CGFloat(0)
            animation.toValue = 2 * CGFloat.pi
            animation.duration = 1
            animation.repeatCount = .infinity
            animation.isRemovedOnCompletion = false
            layer.add(animation, forKey: animation.keyPath)
        }
    
    }
    

    结果:

    【讨论】:

      猜你喜欢
      • 2013-01-11
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多