美文网首页
NSWindowController (窗口控制器)

NSWindowController (窗口控制器)

作者: zhongxiaoyue | 来源:发表于2020-05-13 18:01 被阅读0次

NSWindowController

  • NSWindowController是用来管理window的控制器,能够管理xibstoryboard文件中加载的窗口视图。在Document-Based应用中,NSWindowController也负责创建和管理document的window
  • NSWindowController在基于UI界面的应用中,管理不同场景多个界面窗口的切换,可以说起了非常重要的作用。
  • 创建基于xib的一个NSWindowController类后就自动完成了NSWindow的创建,因此一般情况下很少单独去创建一个独立的NSWindow,只需要调用NSWindowController的showWindow方法显示window就可以了。

加载过程

1. 使用Xib

  • 1). LoadNib: NSApplication运行后加载xib文件
  • 2). orderFront:创建window对象显示window
  • 3). makeKey:app启动完成后,使当前window成为keyWindow

2. 使用Storyboard

  • 1). LoadNib: NSApplication运行后加载Storyboard文件
  • 2). makeKeyAndOrderFront:等价执行了orderFrontmakeKey

关闭过程

  • 1). 执行NSWindow的close方法
  • 2). 执行orderOut方法

NSWindowDelegate

常用代理

    1. 调整Windows大小
// 窗口大小将要变更
func windowWillResize(NSWindow, to: NSSize) -> NSSize
// 窗口大小已经变更
func windowDidResize(Notification)
    1. 最小化Windows
// 窗口将要最小化
func windowWillMiniaturize(Notification)
// 窗口已经最小化
func windowDidMiniaturize(Notification)
    1. 全屏Windows
// 窗口即将进入全屏模式
func windowWillEnterFullScreen(Notification)
// 窗口已进入全屏模式
func windowDidEnterFullScreen(Notification)
// 窗口即将退出全屏模式
func windowWillExitFullScreen(Notification)
// 窗口已退出全屏模式
func windowDidExitFullScreen(Notification)
    1. 窗口移动
// 窗口将要移动
func windowWillMove(Notification)
// 窗口已移动
func windowDidMove(Notification)
    1. 关闭窗口
// 用户试图关闭窗口,return 是否允许关闭
func windowShouldClose(NSWindow) -> Bool
// 窗口即将关闭
func windowWillClose(Notification)
    1. KeyWindow (接收键盘鼠标事件的窗口)
// 窗口已成为KeyWindow
func windowDidBecomeKey(Notification)
// 窗口已退出KeyWindow状态
func windowDidResignKey(Notification)

常见问题

1.实现懒加载的属性方法

lazy var myWindow = { () -> NSWindow in 
    let frame = CGRect(x: 0, y: 0, width: 400, height: 280)
    let style : NSWindow.StyleMask = [NSWindow.StyleMask.titled,NSWindow.StyleMask.closable,NSWindow.StyleMask.resizable]
    //创建window
    let myWindow = NSWindow(contentRect:frame, styleMask:style, backing:.buffered, defer:false)
    myWindow.title = "New Create Window"
    return NSWindow.init()
}()

2.定义按钮的点击事件,显示myWindow

func showWindowAction(_ sender: NSButton) {
    self.myWindow.makeKeyAndOrderFront(self)
}

你会发现只有第一次你可以正常的呼出myWindow显示到屏幕上,当你关闭这个window。再次点击button时程序crash了!
这是因为我们虽然强引用了myWindow,但是对于window的释放,系统是特殊处理,只要关闭就释放了.

  1. 使用NSWindowController管理Window
lazy var myWindowController = { () -> NSWindowController in
    let myWindowController = NSWindowController.init()
    self.myWindow.windowController = myWindowController
    myWindowController.window = self.myWindow
    
    return myWindowController
}()

这样重新运行App,反复关闭window在点击button打开,没有crash,一切很正常。
这样我们可以得出一个结论:手工创建的NSWindow,关闭后系统会检查这个window有没有
controller引用它,有的话就不会释放这个window对象
。xib中创建的window则没有这个问题。


AppDelegate中Window管理分离

新建一个NSWindowArchitecture项目工程
MainMenu.xib中默认生成一个Window,这个Window是由AppDelegate负责管理的,从应用的单一职责划分的原则考虑,Window适合由独立的NSWindowController去管理

删除点击Window对象

新建一个文件AppMainWindowController,继承NSWindowController,勾选使用xib修改AppMainWindowController中默认的代码,增加窗口居中显示,返回window的xib文件名。

class AppMainWindowController: NSWindowController {

    override func windowDidLoad() {
        super.windowDidLoad()
    
        // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
        window?.center()
    }
    
    override var windowNibName: NSNib.Name? {
        get{
            return NSNib.Name(rawValue: "AppMainWindowController")
        }
    }
}

AppDelegate中增加AppMainWindowController的相关代码

class AppDelegate: NSObject, NSApplicationDelegate {

    lazy var windowController: AppMainWindowController = {
        let wondowVC = AppMainWindowController()
        return wondowVC
    }()

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        
        self.windowController.showWindow(self)
    }
}

直接使用xib创建的工程和分离window调整后的架构对比,可以看出架构2在扩展和维护性方面都代于架构1


如果我们创建工程的时候勾选是使用Storyboard选项,系统会创建Window ControllerView Controller Scene不同的分层的场景,这种架构划分是非常合理的。所以推荐使用Storyboard来完成工程创建.

相关文章

网友评论

      本文标题:NSWindowController (窗口控制器)

      本文链接:https://www.haomeiwen.com/subject/nytinhtx.html