NSWindow(窗口对象)

一.NSWindow

  • NSWindow窗口是应用UI界面视图的容器,它负责接收用户的鼠标键盘等系统事件,转发消息到相关的接收者对象。AppKit提供的一些子类化的窗口还可以实现一些辅助交互功能,比如文件打开保存的对话框,字体颜色选择器等等。
  • 每个应用启动后至少会打开一个窗口。当你运行多个应用App时,屏幕上会有多个窗口界面。我们把当前用户正在工作的应用的窗口称为活动或激活的窗口,其他应用的窗口相应的称为非活动的窗口。活动窗口顶部的title bar部分的颜色是高亮灰色选中状态。

KeyWindow
可以接收输入事件(键盘,鼠标,触控板等外设)的窗口对象称为ZkeyWindowZ;
MainWindow
当前的
活动窗口也称为mainWindow一个时刻只能有一个keyWindow和一个mainWindow。**


二.窗口界面的组成

窗口对象包括titleBar, contentView内容视图, contentBorder底部边框区。titleBar上面包括控制按钮、标题,如下图所示。



三.模态窗口

有些特殊场景需要限制用户只能处理完当前的窗口的任务,完成任务后关闭它才能继续操作其他的窗口,这种窗口称为模态窗口(Modal Window)。
模态窗口分为两种

  • 1.Modal Window

这种window比较霸道,当它启动后,此时只有这个window可以接收响应用户操作,无法切换到其他窗口操作,其他窗口也不能接收处理系统内部的各种事件

使用NSApplication的runModal方法来创建Modal window

@IBAction func showModalWindow(_ sender: NSButton) {
    NSApplication.shared.runModal(for: modalWindow)
    modalWindow.center()
}

使用stopModal方法来结束模态.如果用户直接点击了窗口顶部最左侧的关闭按钮,窗口关闭了,但是整个应用仍然处于模态,任何操作都无法得到响应.正确的做法是监听窗口关闭事件,增加结束模态的方法调用.

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application
    NotificationCenter.default.addObserver(self, selector:#selector(self.windowClose(_:)),  name: NSWindow.willCloseNotification, object: nil)
}

@objc func windowClose(_ aNotification: Notification){
    NSApplication.shared.stopModal()
}
  • 2.Modal Session

比起Modal windows,Modal sessions方式创建的window稍微温和一些,允许响应快捷键和系统菜单,比如字体颜色选择这些panel面板.

@IBAction func showSessionsWindow(_ sender: NSButton) {
    sessionCode = NSApplication.shared.beginModalSession(for: self.modalWindow)
}

结束Modal sessions窗口,使用sessionCode做为参数来关闭Modal sessions窗口.跟上面的模态处理一样需要注册窗口关闭事件来正常执行模态状态关闭.

@objc func windowClose(_ aNotification: Notification){
    
    if let sessionCode = sessionCode {
        NSApplication.shared.endModalSession(sessionCode)
        self.sessionCode = nil
    }
}

四.创建窗口

使用NSWindow类创建窗口对象,除了frame参数,还需要制定styleMask来确定窗口样式风格.

func createWindow() {
    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
    myWindow = NSWindow(contentRect:frame, styleMask:style, backing:.buffered, defer:false)
    myWindow.title = "New Create Window"
    //显示window
    myWindow.makeKeyAndOrderFront(self);
    //居中
    myWindow.center()
}

1. styleMask:表示窗口风格的参数

  • borderless:没有项部标题栏和控制按钮。
  • titled: 有顶部标题栏边框。
  • closable: 带有关闭按钮。
  • miniaturizable:带有最小化按钮。
  • resizable:带有恢复按钮。
  • texturedBackground:带纹理背景窗口。
  • uitTitlAndToobarar窗口的标题栏按钮区和窗口顶部的标题区融合为一体。
  • fullScreen:全屏显示。
  • fullSizeContentView:内容视图占据整个窗口大小。
  • utilityWindow: NSPanel 类型的窗口。
  • docModalWindow:模态文档,NSPanel 类型窗口。
  • nonactivatingPanel:一种非活动主应用NSPanel类型窗口,点击这种面板不会导致主应用窗口从活动状态变为非活动状态.
  • hudWindow: HUD黑色风格窗口,只有NSPanel类型窗口支持.

2. backing: 窗口绘制的缓存模式

  • retained: 兼容老系统参数,基本很少用到.
  • nonretained: 不缓存直接绘制.
  • buffered: 缓存绘制.

五. 窗口通知

当窗口状态变化时候,系统会发出相关通知消息.下面是一些典型的窗口通知事件,更多通知事件请参考NSWindow类文件中的定义.

  • NSWindowDidBecomeKeyNotification:窗口成为keyWindow
  • NSWindowDidBecomeMainNotification:窗口成为mainWindow
  • NSWindowDidMoveNotification:窗口移动
  • NSWindowDidResignKeyNotification:窗口不再是keyWindow
  • NSWindowDidResignMainNotification:窗口不再是mai nWindow
  • NSWindowDidResizeNotification:窗口大小改变
  • NSWindowWillCloseNotification:关闭窗口
  • NSWindowDidMiniaturizeNotification:窗口最小化

六.窗口内容(ContentView)

open var contentView: NSView?

@available(OSX 10.10, *)
open var contentViewController: NSViewController?

1.可以使用自定义的NSView或NSViewController的view,添加到contentView

self.window.contentView?.addSubview(myView)

2.macOS 10.10系统及以上,创建一个NSViewController的子类,实例化后赋值给NSWindow的contentViewController.

self.window.contentViewController = myViewController

七.窗口的创建和管理

  • 般情况下很少需要单独创建和管理窗口NSWindow对象.NSWindow的创建都是基于项目场景模版创建,或者通过NSWindowController创建管理的.
  • 新建一个项目,工程中会自动生成的MainMenu.xib中会包含一个Window对象,这个Window是由AppDelegate管理的.
  • 新建一个项目,勾选Create Document-Based Application,自动生成的Document.xib会包含一个Window对象,这个Window是由NSDocument文档类来管理的.
  • 新建一个NSWindowCotrller的子类WindowContoller,勾选使用xib, 自动生成的WindowController.xib会包含一个Window对象.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343