macOS 開發(fā)-NSView實踐-提個醒

IT人士是久坐一族中核心大軍件炉,在學習NSView的相關知識后峻凫, 我們來通過視圖的基本功能來開發(fā)一個簡單的應用纫事,用于定時提醒我們從座位上起來活動一下。

實現(xiàn)思路

在開發(fā)之前所灸,我們先來梳理下思路:

  1. 我們需要一個計時器丽惶,定期上報事件;
  2. 在指定時間里爬立,彈出一個強制提醒钾唬,提醒用戶起來活動;
  3. 彈出提醒時禁止執(zhí)行其它操作侠驯,需要用戶手動關閉提醒抡秆。

核心知識

視圖

《NSView》 基礎知識一節(jié)已經(jīng)介紹過基本功能,全部功能的api可參考 《NSView API》 一節(jié)吟策,提個醒應用將用到以下api:

// 將視圖設置為全屏模式
func enterFullScreenMode(NSScreen, withOptions: [NSView.FullScreenModeOptionKey : Any]?) -> Bool
// 指示視圖退出全屏模式
func exitFullScreenMode(options: [NSView.FullScreenModeOptionKey : Any]?)
// 視圖是否處于全屏模式
var isInFullScreenMode: Bool

計時器

計時器Timer儒士,后面會有專門的內容會詳情介紹,這里只簡單使用以下api:

class func scheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Void) -> Timer

編碼實現(xiàn)

創(chuàng)建基礎工程

可參考《開發(fā)環(huán)境與基礎工程創(chuàng)建》一節(jié)內容創(chuàng)建一個帶Storyboard的工程檩坚,或者直接復制Demo中的空白工程進入開發(fā)着撩。

代碼實現(xiàn)

定時執(zhí)行任務

假設我們在進入應用后, 每20秒彈出一人提醒匾委,我們就可以通過計時器來實現(xiàn):

lazy var timer: Timer = {
        let timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(20), repeats: true) { _ in
        self.enterFullScreen()
    }
    return timer
}()

override func viewDidLoad() {
    super.viewDidLoad()
    DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 20) {
        DispatchQueue.main.async {
            self.timer.fire()
        }
    }
}

因為暫時沒有設置啟動提醒的開頭拖叙,我們在進入應用的時候,就使用GCD來實現(xiàn)第一次計時來開啟提醒赂乐。關于GCD的內容這里就不展示討論薯鳍,后面內容再詳細講解。

進入全屏提醒

我們可以通過NSScreen.main獲取當前屏幕沪猴,然后通過使用enterFullScreenMode使頁面進入全屏顯示辐啄,如果頁面已經(jīng)是全屏顯示則不需要再次執(zhí)行:

func enterFullScreen() {
    guard let screen = NSScreen.main else {
        return
    }
    if !view.isInFullScreenMode {
        view.enterFullScreenMode(screen, withOptions: [NSView.FullScreenModeOptionKey.fullScreenModeAllScreens : true])
    }
}

當電腦有多個顯示器的時候,可以通過NSScreen.screens獲取你想在那個屏幕上顯示提示运嗜,NSScreen.main是當前獲取焦點的屏幕。

退出全屏

當頁面已經(jīng)全屏的時候悯舟,我們可以通過exitFullScreenMode退出全屏模式:

private func exitFullScreen() {
    view.exitFullScreenMode(options: [NSView.FullScreenModeOptionKey.fullScreenModeAllScreens : true])
}

手動退出按鈕

當頁面在全屏模式下担租,所有可以操作的界面都會被擋住,所以我們需要提供一個退出按鈕來實現(xiàn)退出全屏:

private func setupSubviews() {
    view.addSubview(confirmButton)
    view.addConstraint(_LayoutConstraintMake(confirmButton, .centerY, .equal, view, .centerY))
    view.addConstraint(_LayoutConstraintMake(confirmButton, .centerX, .equal, view, .centerX))
    view.addConstraint(_LayoutConstraintMake(confirmButton, .width, .equal, nil, .width, 100))
    view.addConstraint(_LayoutConstraintMake(confirmButton, .height, .equal, nil, .height, 28))
}

@objc private func confirm() {
    view.isInFullScreenMode ? exitFullScreen() : enterFullScreen()
}

由于暫沒有引入任何第三方autolayout庫抵怎,這里我們簡單將系統(tǒng)的約束生成封裝成_LayoutConstraintMake:

@inline(__always)
internal func _LayoutConstraintMake(_ item: AnyObject, _ attr1: NSLayoutConstraint.Attribute, _ related: NSLayoutConstraint.Relation, _ toItem: AnyObject? = nil, _ attr2: NSLayoutConstraint.Attribute = .notAnAttribute, _ constant: CGFloat = 0, priority: NSLayoutConstraint.Priority = NSLayoutConstraint.Priority(1000), multiplier: CGFloat = 1, output: UnsafeMutablePointer<NSLayoutConstraint?>? = nil) -> NSLayoutConstraint {
    let c = NSLayoutConstraint(item:item, attribute:attr1, relatedBy:related, toItem:toItem, attribute:attr2, multiplier:multiplier, constant:constant)
    c.priority = priority
    if output != nil {
        output?.pointee = c
    }
    return c
}

待完善功能

到此奋救,一個簡單的提醒應用已經(jīng)基本成型,但是它只有最基礎的全屏提醒功能反惕,離一個完整的應用還有很遠的距離尝艘,比如還存在以下的問題:

  1. 進入全屏的時候,計時器沒有停止姿染,還在繼續(xù)計算背亥,而不是進入全屏提醒時停止計時,退出全屏時重新計時;
  2. 不能設置提醒的時間間隔與提醒方案狡汉;
  3. 應用一進入時就開始計時娄徊,不能手動選擇是否運行等。

這里留下以上問題盾戴,讀者可以嘗試去解決以上問題寄锐,或者在學習后面的內容后,再回來完善這個應用尖啡。

小結

NSView是最基礎的視圖橄仆,擁有非常多的API,這里通過一個簡單的應用來了解學習其中一兩個API衅斩,但這只是冰山一角沿癞,所有我匯總了一份NSView API文檔,我們可以看到它擁有非常龐大API矛渴,讓人望而卻步椎扬。但不用擔心,隨著我們對macOS的更深入學習具温,我們會慢慢理解這些接口到底是做什么的蚕涤,它們存在的意義是什么。

完整的項目源碼請訪問這里:https://github.com/dengyhgit/macOS-Dev-Demo/tree/master/Reminder铣猩, 如對你有幫忙揖铜,別忘點亮小??。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末达皿,一起剝皮案震驚了整個濱河市天吓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峦椰,老刑警劉巖龄寞,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汤功,居然都是意外死亡物邑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門滔金,熙熙樓的掌柜王于貴愁眉苦臉地迎上來色解,“玉大人,你說我怎么就攤上這事餐茵】蒲郑” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵忿族,是天一觀的道長锣笨。 經(jīng)常有香客問我蝌矛,道長,這世上最難降的妖魔是什么票唆? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任朴读,我火速辦了婚禮,結果婚禮上走趋,老公的妹妹穿的比我還像新娘衅金。我一直安慰自己,他們只是感情好簿煌,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布氮唯。 她就那樣靜靜地躺著,像睡著了一般姨伟。 火紅的嫁衣襯著肌膚如雪惩琉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天夺荒,我揣著相機與錄音瞒渠,去河邊找鬼。 笑死技扼,一個胖子當著我的面吹牛伍玖,可吹牛的內容都是我干的。 我是一名探鬼主播剿吻,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窍箍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丽旅?” 一聲冷哼從身側響起椰棘,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎榄笙,沒想到半個月后邪狞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡办斑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年外恕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乡翅。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖罪郊,靈堂內的尸體忽然破棺而出蠕蚜,到底是詐尸還是另有隱情,我是刑警寧澤悔橄,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布靶累,位于F島的核電站腺毫,受9級特大地震影響,放射性物質發(fā)生泄漏挣柬。R本人自食惡果不足惜潮酒,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邪蛔。 院中可真熱鬧急黎,春花似錦、人聲如沸侧到。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匠抗。三九已至故源,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汞贸,已是汗流浹背绳军。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留矢腻,地道東北人门驾。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像踏堡,于是被迫代替她去往敵國和親猎唁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內容