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閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378