1

我很难让我NSView观察其 parent 的变化NSWindow。我在一个测试项目上尝试了这个,它只NSWindow包含一个MyView子类,NSView只是为了看看我是否遗漏了一些东西。

class MyView: NSView {

    //add observer on awake from nib
    //works fine
    override func awakeFromNib() {
        if let win = self.window {
            win.addObserver(self, forKeyPath: Notification.Name.NSWindowDidBecomeKey.rawValue, options: .new, context: nil)
        }
    }

    //remove observer on dealloc
    //allso works fine
    deinit {
        if let win = self.window {
            win.removeObserver(self, forKeyPath: Notification.Name.NSWindowDidBecomeKey.rawValue)
        }
    }

    //never gets called
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        Swift.print(keyPath ?? "")
        Swift.print("worked!")
    }

    override func draw(_ dirtyRect: NSRect) {
        NSColor.blue.set()
        NSBezierPath.fill(dirtyRect)
    }
} 

我也尝试过这里的建议,但没有运气。我还检查了其他答案,但找不到答案。大多数涵盖使您自己的类 KVO 兼容。我想观察一个 NSWindow 对象。我错过了什么?

4

1 回答 1

1

所以看起来NSWindowDidBecomeKey需要Notification发布到默认NotificationCenter而不是窗口本身。这是有效的正确代码

class MyView: NSView {

    //add observer on awake from nib
    //works fine
    override func awakeFromNib() {
        if let win = self.window {
            NotificationCenter.default.addObserver(self, selector: #selector(self.windowIsKey(_:)), name: .NSWindowDidBecomeKey, object: win)
        }
    }

    //remove observer on dealloc
    //allso works fine
    deinit {
        if let win = self.window {
            NotificationCenter.default.removeObserver(self, name: .NSWindowDidBecomeKey, object: win)
        }
    }

    //now this method is called and works fine
    func windowIsKey(_ notification: Notification) {
        Swift.print("worked!")
    }
} 
于 2016-12-20T05:05:15.450 回答