IT人士是久坐一族中核心大軍件炉,在學習NSView
的相關知識后峻凫, 我們來通過視圖的基本功能來開發(fā)一個簡單的應用纫事,用于定時提醒我們從座位上起來活動一下。
實現(xiàn)思路
在開發(fā)之前所灸,我們先來梳理下思路:
- 我們需要一個計時器丽惶,定期上報事件;
- 在指定時間里爬立,彈出一個強制提醒钾唬,提醒用戶起來活動;
- 彈出提醒時禁止執(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)基本成型,但是它只有最基礎的全屏提醒功能反惕,離一個完整的應用還有很遠的距離尝艘,比如還存在以下的問題:
- 進入全屏的時候,計時器沒有停止姿染,還在繼續(xù)計算背亥,而不是進入全屏提醒時停止計時,退出全屏時重新計時;
- 不能設置提醒的時間間隔與提醒方案狡汉;
- 應用一進入時就開始計時娄徊,不能手動選擇是否運行等。
這里留下以上問題盾戴,讀者可以嘗試去解決以上問題寄锐,或者在學習后面的內容后,再回來完善這個應用尖啡。
小結
NSView
是最基礎的視圖橄仆,擁有非常多的API,這里通過一個簡單的應用來了解學習其中一兩個API衅斩,但這只是冰山一角沿癞,所有我匯總了一份NSView API文檔,我們可以看到它擁有非常龐大API矛渴,讓人望而卻步椎扬。但不用擔心,隨著我們對macOS的更深入學習具温,我們會慢慢理解這些接口到底是做什么的蚕涤,它們存在的意義是什么。
完整的項目源碼請訪問這里:https://github.com/dengyhgit/macOS-Dev-Demo/tree/master/Reminder铣猩, 如對你有幫忙揖铜,別忘點亮小??。