当Tweetbot运行时,在CALayer动画期间关闭窗口时OS X应用程序冻结

Fan*_*ude 5 macos cocoa swift

我做了一个自定义NSControl,将其用作自定义图层备份按钮.

MyButton实例收到mouseDownmouseUp发生事件时,它会改变它backgroundLayerbackgroundColor和它textLayerforegroundColor.

它使用图层,因此隐式动画更改.

但是mouseUp如果鼠标在MyButton实例框架内,我通过sendAction(_:to:)方法调用链接动作.

我将操作链接到关闭当前窗口并打开另一个窗口的方法,但有时在第二个窗口出现后应用程序冻结.

我尝试了几件事情,它似乎与图层动画有关,也许在关闭窗口之前要做的事我不知道.

更新:这是Tweetbot!如果Tweetbot正在运行它会冻结应用程序!一旦我退出它,应用程序就会再次响应.

您可以在这里找到一个示例项目:https : //dl.dropboxusercontent.com/u/378166/CALayerFreeze.zip
(请注意,在发生错误之前,您有时需要多次尝试)

这是代码MyButton.

class MyButton: NSControl {
    let title = "Click me!"

    // Init
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }

    deinit {
        trackingAreas.forEach { self.removeTrackingArea($0) }
    }

    // Layer + Tracking Area configuration
    var backgroundLayer = CALayer()
    var textLayer = CATextLayer()

    func setup() {
        wantsLayer = true

        backgroundLayer.frame = NSRect(origin: .zero, size: frame.size)
        backgroundLayer.backgroundColor = NSColor.whiteColor().CGColor
        layer?.addSublayer(backgroundLayer)

        textLayer.frame = NSRect(origin: .zero, size: frame.size)
        textLayer.string = title
        textLayer.foregroundColor = NSColor.blackColor().colorWithAlphaComponent(0.64).CGColor
        layer?.addSublayer(textLayer)

        addTrackingArea(
            NSTrackingArea(
                rect: bounds,
                options: [.MouseEnteredAndExited, .EnabledDuringMouseDrag, .ActiveInKeyWindow],
                owner: self,
                userInfo: nil
            )
        )
    }

    // States
    private func normal() {
        // ——— COMMENTING THIS MAKES THE BEACHBALL GO AWAY
        backgroundLayer.backgroundColor = NSColor.whiteColor().CGColor
        textLayer.foregroundColor = NSColor.blackColor().colorWithAlphaComponent(0.64).CGColor
    }

    private func highlight() {
        // ——— COMMENTING THIS MAKES THE BEACHBALL GO AWAY
        backgroundLayer.backgroundColor = NSColor.grayColor().CGColor
        textLayer.foregroundColor = NSColor.whiteColor().colorWithAlphaComponent(0.64).CGColor
    }

    // Tracking events
    var isMouseDown = false

    override func mouseDown(theEvent: NSEvent) {
        super.mouseDown(theEvent)
        isMouseDown = true
        highlight()
    }

    override func mouseUp(theEvent: NSEvent) {
        super.mouseUp(theEvent)
        isMouseDown = false
        normal()

        if frame.contains(convertPoint(theEvent.locationInWindow, toView: self)) {
            sendAction(action, to: target)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)