NSWindowDelegate无法接收窗口拖拽调整大小通知问题排查
解决NSWindowDelegate拖拽调整大小时不触发resize方法的问题
常见排查与修复方向
1. 窗口代理被意外覆盖
这是最容易踩的坑,优先检查:
- 打开你的Storyboard/XIB文件,确认窗口的
Delegate出口没有绑定到其他对象(比如ViewController)。如果界面编辑器里已经设置了delegate,代码中window?.delegate = self会被覆盖,或者后续其他逻辑可能重置了代理。 - 拖拽窗口前验证代理有效性:在
MyWindowController中添加如下代码,切换窗口焦点时打印当前代理:
如果输出不是func windowDidBecomeKey(_ notification: Notification) { print("当前窗口代理:\(window?.delegate)") }MyWindowController实例,说明代理已经被修改。
2. WindowController未被强引用
如果MyWindowController是临时创建未被持有,会被ARC自动释放,导致代理失效:
- 检查创建WindowController的代码,确保有强引用持有它。比如在AppDelegate中:
class AppDelegate: NSObject, NSApplicationDelegate { var mainWindowController: MyWindowController! // 强引用持有实例 func applicationDidFinishLaunching(_ aNotification: Notification) { mainWindowController = MyWindowController(windowNibName: "MyWindow") mainWindowController.showWindow(nil) } }
3. 用通知中心验证事件是否触发
如果代理方法没响应,先确认resize事件本身是否触发:
在windowDidLoad中添加通知监听:
override func windowDidLoad() { super.windowDidLoad() window?.delegate = self // 注册resize通知 NotificationCenter.default.addObserver(self, selector: #selector(onWindowResized(_:)), name: NSWindow.didResizeNotification, object: window) } @objc func onWindowResized(_ notification: Notification) { print("通知收到窗口resize") }
- 若拖拽时能收到通知:说明是代理绑定的问题,回到第一步排查代理覆盖情况。
- 若也收不到通知:检查窗口是否允许调整大小:
确保print("窗口是否可调整:\(window?.styleMask.contains(.resizable) ?? false)").resizable在窗口的styleMask中。
4. 自定义NSWindow子类干扰
如果你使用了自定义NSWindow子类,检查是否重写了resize相关方法但未调用super:
class CustomWindow: NSWindow { override func willResize(_ sender: NSWindow, to frameSize: NSSize) -> NSSize { // 必须调用super,否则代理方法不会触发 let newSize = super.willResize(sender, to: frameSize) // 你的自定义逻辑 return newSize } }
内容的提问来源于stack exchange,提问作者fsctl
相关产品推荐
相关产品推荐

