本文翻譯自 raywenderlich.com 的 How to Use NSTouchBar on macOS惰赋,已咨詢對方網(wǎng)站罕伯,可至多翻譯 10 篇文章莫鸭。
各位若有英語閱讀能力的話,還是先打賞然后去閱讀英文原吧??。
綜上赚哗,此翻譯版本僅供參考,謝絕轉載孤钦。也歡迎你點擊我的頭像查看我翻譯的其他 macOS 開發(fā)教程??
對了我跟著這個教程敲代碼的時候發(fā)現(xiàn)文中所有的
@available(OSX 10.12.1, *)
其實應為@available(OSX 10.12.2, *)
择葡,但是出于對原文的尊重沒有修改,請各位注意~
等了好久好久終于等到今天之后击你,Apple 終于發(fā)布了新款的 MacBook Pro玉组,它最惹人矚目的應該就是那塊(小小的)觸屏了吧。
新款設備用全新的 Touch Bar 替代了原有的功能鍵丁侄,它們可擴展惯雳、支持多點觸控,更重要的是绒障,Touch Bar 對開發(fā)者們完全開放吨凑,這意味著你的 macOS app 可以獲得一種全新的交互方式。
如果你是一個 macOS 開發(fā)者户辱,你一定很希望自己的 app 能夠立刻使用上這項前沿科技鸵钝。在這個教程中,我會將向你們展示如何使用全新的 NSTouchBar
API 來為你的 macOS app 創(chuàng)建一個動態(tài)的 Touch Bar庐镐。
注意:這個教程需要 Xcode 8.1 或更高版本以及 macOS 10.12.1 (Build 16B2657) 或更高版本恩商,否則的話你將無法運行 Touch Bar 模擬器。你可以在 ? → 關于本機里點擊數(shù)字版本號來查看 build 版本必逆。
如果你的版本不夠怠堪,你可以在 Apple 的網(wǎng)站上 下載。
Touch Bar 是個啥名眉?
如上文所述粟矿,Touch Bar 是一塊安裝在鍵盤上方的細長形的觸摸屏,它允許用戶使用一種全新的方式來與 app(以及 Mac)進行交互损拢。
在 Touch Bar 上有三個默認的部分:
- 系統(tǒng)按鈕:根據(jù)運行的 app陌粹,這里將會顯示一個系統(tǒng)級的按鈕,比如 esc福压;
- App 區(qū)域:你的 app 可以控制的顯示區(qū)域掏秩,也就是我們的主舞臺;
- 控制條:這里用于顯示你熟悉的控制按鈕荆姆,比如亮度蒙幻、音量等。
和其它許多 Apple 的新科技一樣胆筒,Touch Bar 也擁有自己的《人機交互則例(Human Interface Guidelines)》邮破,為了你的 app 和其它 Mac app 擁有統(tǒng)一的用戶體驗,你應當遵循這份則例。你可以點擊這里閱讀它决乎。
概括說來队询,這份則例中比較重要的幾點有:
- App 中的某個功能不應該只能在 Touch Bar 中使用:即使部份用戶還未升級到最新的硬件,你的 app 也應該盡量為他們提供一樣的功能构诚。如果你決定為 Touch Bar 加入某些功能蚌斩,請確保這個功能也能在 app 的其他某處也可以訪問到。另外 Touch Bar 是可以被用戶禁用的范嘱,所以也別太指望你的用戶能一直看到它送膳;
- Touch Bar 是鍵盤的延伸,而不是一個顯示屏:誠然丑蛤,Touch Bar 是一個顯示屏叠聋,但是它不是顯示器的延伸,而是一個與 app 交互的窗口受裹。你不應該在 Touch Bar 上用滾來滾去的內容或 blingbling 的警告打擾用戶的視線碌补;
- 快速響應:用戶在鍵盤上按下一個真實的按鍵時,按鍵會立即給予一個反饋(也就是被按下去了)棉饶。同理厦章,用戶在 Touch Bar 上按下一個虛擬按鈕時,你也應該給他們提供即時的反饋照藻。
如何讓你的 app 支持 Touch Bar
要讓你的 app 支持 Touch Bar袜啃,你需要使用 Apple 提供的兩個類:NSTouchBar
和 NSTouchBarItem
(當然還有他們的子類)。
某些 NSTouchBarItem
的子類提供了這些功能:
- Slider:滑動調節(jié)某個值幸缕;
- Popover:把更多功能藏入一個二級菜單中群发;
- Color Picker:和名字一樣,用來選取顏色的咯???♀?发乔;
- Custom:這個子類是你的天下熟妓,你可以在它的里面塞入文本、按鈕以及其他各種各樣的控件栏尚。
從文字大小顏色到圖片內容起愈,你可以隨意自定義你的 item,從而為你的用戶提供一個傳統(tǒng)鍵盤無法提供的抵栈、更加牛×的交互方式坤次,但是請時刻請謹記《人機交互則例》」啪ⅲ現(xiàn)在我們要開始動工啦。
準備開始
在開始敲代碼之前缰猴,請先點擊這里下載初始項目的源代碼产艾。
我們要編寫的 app 是一個簡單的旅行記錄 app。打開初始項目,如果你的設備不支持 Touch Bar闷堡,請點擊 Xcode 菜單欄上的 Window → Show Touch Bar隘膘,Touch Bar 的模擬器就會出現(xiàn)在屏幕上。
編譯并運行你的 app杠览,你將會看到 Touch Bar 上除了 esc 按鈕和控制條以外空空如也弯菊。
我們要做的第一步是告訴系統(tǒng)我們的 app 需要自定義 Touch Bar。打開 AppDelegate.swift踱阿,將這些代碼添加到 applicationDidFinishLaunching(_:)
方法中:
func applicationDidFinishLaunching(_ aNotification: Notification) {
if #available(OSX 10.12.1, *) {
NSApplication.shared().isAutomaticCustomizeTouchBarMenuItemEnabled = true
}
}
這些代碼將會幫你搞定啟用 Touch Bar 所需要的各種操作管钳,(在寫這篇文章的時候)Xcode 還沒有 macOS 10.12.1 的配套 SDK,所以你需要在 Touch Bar 相關的代碼周邊添加 #available(OS X 10.12.1, *)
软舌,當然如果你忘了這件事才漆,Xcode 會給你一個溫馨的提醒??。
打開 WindowController.swift佛点,找到 makeTouchBar()
醇滥,這個方法用于檢測 ViewController
是否含有一個可以被返回的 Touch Bar,如果有超营,它會把這個 Touch Bar 返回給 Window鸳玩,然后呈現(xiàn)給用戶。現(xiàn)在糟描,我們還沒有創(chuàng)建 Touch Bar怀喉,所以什么也不會發(fā)生。
在你開始創(chuàng)建自己的 Touch Bar 和 Touch Bar Item 之前船响,你需要注意這些類都需要獨一無二的 identifier(標識符)躬拢,打開 TouchBarIdentifiers.swift,你將能看到兩個擴展定義了一些標識符:NSTouchBarCustomizationIdentifier
和 NSTouchBarItemIdentifier
见间。
前往 ViewController.swift聊闯,并把這些帶碼添加到文件最后 // MARK: - TouchBar Delegate
注釋的后方:
@available(OSX 10.12.1, *)
extension ViewController: NSTouchBarDelegate {
override func makeTouchBar() -> NSTouchBar? {
// 1
let touchBar = NSTouchBar()
touchBar.delegate = self
// 2
touchBar.customizationIdentifier = .travelBar
// 3
touchBar.defaultItemIdentifiers = [.infoLabelItem]
// 4
touchBar.customizationAllowedItemIdentifiers = [.infoLabelItem]
return touchBar
}
}
在此處,通過重寫 makeTouchBar()
方法米诉,你給你的 View 或 Window 創(chuàng)建了一個 Touch Bar菱蔬,在這個方法中:
- 創(chuàng)建一個新的
TouchBar
并設置它的 delegate; - 設置 customizationIdentifier(自定義標識符)史侣,每個
TouchBar
和TouchBarItem
都需要一個獨一無二的標識符拴泌; - 設置 Touch Bar 的默認 item 標識符,這將會告訴 Touch Bar 它將會容納哪些 item惊橱;
- 這一步是允許用戶可以自定義的 item蚪腐。作為參考,你可以打開 Finder税朴,點擊菜單欄上的 顯示 → 自定 Multi-Touch Bar看看自定義 Touch Bar 是什么效果回季。
接下來家制,我們還需要設置 .infoLabelItem
是什么樣子的,在同一個 extension 中添加:
func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? {
switch identifier {
case NSTouchBarItemIdentifier.infoLabelItem:
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = NSTextField(labelWithString: "\u{1F30E} \u{1F4D3}")
return customViewItem
default:
return nil
}
}
通過實現(xiàn)touchBar(_:makeItemForIdentifier:)
方法泡一,你可以自定義你的 Touch Bar Item颤殴,在段代碼里,你創(chuàng)建了一個 NSCustomTouchBarItem
鼻忠,并把它的 view
設置為了 NSTextField
涵但。
編譯并運行你的 app,你可以看到 Touch Bar 多了一個 item粥烁。
耶??贤笆!通過一番努力你得到了……兩個 emoji…好吧,現(xiàn)在我們來添加一些別的控件讨阻。
Text Field 和 Scrubber
在 makeTouchBar()
里芥永,把 touchBar.defaultItemIdentifiers = [.infoLabelItem]
修改為:
touchBar.defaultItemIdentifiers = [.infoLabelItem, .flexibleSpace, .ratingLabel, .ratingScrubber]
這些代碼會讓 Touch Bar 顯示三個 item:一個 label、一個 scrubber 以及一個 .flexibleSpace
钝吮。這是一個動態(tài)的間距埋涧,它可以把各種 item 按組進行整潔的分類。此外你還可以使用 .fixedSpaceSmall
和 .fixedSpaceLarge
這兩個固定間距奇瘦。
和之前的那個 label 一樣棘催,你也需要自定義這些 item,把這些 cases
添加到 touchBar(_:makeItemForIdentifier:)
里的 switch
:
case NSTouchBarItemIdentifier.ratingLabel:
// 1
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = NSTextField(labelWithString: "Rating")
return customViewItem
case NSTouchBarItemIdentifier.ratingScrubber:
// 2
let scrubberItem = NSCustomTouchBarItem(identifier: identifier)
let scrubber = NSScrubber()
scrubber.scrubberLayout = NSScrubberFlowLayout()
scrubber.register(NSScrubberTextItemView.self, forItemIdentifier: "RatingScrubberItemIdentifier")
scrubber.mode = .fixed
scrubber.selectionBackgroundStyle = .roundedBackground
scrubber.delegate = self
scrubber.dataSource = self
scrubberItem.view = scrubber
scrubber.bind("selectedIndex", to: self, withKeyPath: #keyPath(rating), options: nil)
return scrubberItem
一步一步來看:
- 為「評分」新建了一個新的 label item耳标;
- 然后創(chuàng)建一個新的 item 用來展示
NSScrubber
醇坝。這是一個 Touch Bar 特有的控件,它允許你在若干個項目中進行選擇次坡。Scrubber 需要一個代理來處理事件呼猪,你需要做的是設置一個delegate
(初始項目的源代碼已經(jīng)在 ViewController 里實現(xiàn)過這個協(xié)議了)。
編譯并運行你的 app砸琅,你將會看到 Touch Bar 里多出了兩個新的 item宋距,當你點擊某個 scrubber 里的項目后,在 app 的主窗口里能看到數(shù)值的調整症脂。
Segmented Control
接下來谚赎,我們來添加一個 Segmented Control。這個控件沒有使用 Delegate 模式诱篷,因此這剛好可以讓你體驗一下怎么設置 Touch Bar 里的 Target-Action(目標動作)壶唤。回到 makeTouchBar()
中棕所,把這三個 item 添加到 defaultItemIdentifiers
里:
touchBar.defaultItemIdentifiers = [.infoLabelItem, .flexibleSpace, .ratingLabel, .ratingScrubber, .flexibleSpace, .visitedLabelItem, .visitedItem, .visitSegmentedItem]
以及把最后的三個 case
添加到 touchBar(_:makeItemForIdentifier:)
中:
case NSTouchBarItemIdentifier.visitedLabelItem:
// 1
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = NSTextField(labelWithString: "Times Visited")
return customViewItem
case NSTouchBarItemIdentifier.visitedItem:
// 2
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = NSTextField(labelWithString: "--")
customViewItem.view.bind("value", to: self, withKeyPath: #keyPath(visited), options: nil)
return customViewItem
case NSTouchBarItemIdentifier.visitSegmentedItem:
// 3
let customActionItem = NSCustomTouchBarItem(identifier: identifier)
let segmentedControl = NSSegmentedControl(images: [NSImage(named: NSImageNameRemoveTemplate)!, NSImage(named: NSImageNameAddTemplate)!], trackingMode: .momentary, target: self, action: #selector(changevisitedAmount(_:)))
segmentedControl.setWidth(40, forSegment: 0)
segmentedControl.setWidth(40, forSegment: 1)
customActionItem.view = segmentedControl
return customActionItem
一步一步看:
- 和之前一樣闸盔,創(chuàng)建一個簡單的 Label;
- 創(chuàng)建另一個 Label橙凳,但這一次使用 bind 來把 Label 要顯示的文本綁定到一個屬性上蕾殴;
- 最后,創(chuàng)建一個 Segmented Control岛啸,并設置它的 action钓觉。你可以看到,為它設置一個 action 和其他常見控件是完全一樣的坚踩。
編譯并運行荡灾,除了 Scrubber,你現(xiàn)在還可以和 Segmented Control 交互了瞬铸。此外批幌,在 Touch Bar 里修改一個數(shù)值,app 的主窗口中也會顯示出來嗓节,反之亦然荧缘。
彩色按鈕
能讓用戶使用 Touch Bar 來進行「保存」操作是一個不錯的點子,因為這個按鈕和別的按鈕都不一樣拦宣,我們可以把它設置成綠色的截粗。你可以使用 NSButton
的 bezelColor
屬性來給它設置一個特殊的顏色。
打開 TouchBarIdentifiers.swift鸵隧,在 NSTouchBarItemIdentifier
extension 里绸罗,添加這些代碼:
static let saveItem = NSTouchBarItemIdentifier("com.razeware.SaveItem")
這將會從頭開始創(chuàng)建一個標識符,以此允許你在 Touch Bar 里添加一個 item豆瘫。
返回 ViewController.swift珊蟀,添加一個新的 .flexSpace
和 .saveItem
到 Touch Bar 的 defaultItemIdentifiers
里:
touchBar.defaultItemIdentifiers = [.infoLabelItem, .flexibleSpace, .ratingLabel, .ratingScrubber, .flexibleSpace, .visitedLabelItem, .visitedItem, .visitSegmentedItem, .flexibleSpace, .saveItem]
基本上完成了,最后一步是對按鈕進行一些設置外驱。在 touchBar(_:makeItemForIdentifier:)
中添加最后一個 case
:
case NSTouchBarItemIdentifier.saveItem:
let saveItem = NSCustomTouchBarItem(identifier: identifier)
let button = NSButton(title: "Save", target: self, action: #selector(save(_:)))
button.bezelColor = NSColor(red:0.35, green:0.61, blue:0.35, alpha:1.00)
saveItem.view = button
return saveItem
通過 bezelColor
育灸,你已經(jīng)把這個按鈕成功地修改成了綠色。
編譯并運行略步,你會看到 Touch Bar 上有了一個綠色的按鈕描扯,它和窗口中的 Save 按鈕擁有一樣的功能。
現(xiàn)在該做些啥趟薄?
你可以點擊這里下載最終完成的項目绽诚。
這些就是 Touch Bar 的基礎了。顯然杭煎,Apple 希望 Touch Bar 的開發(fā)過程越簡單越好恩够,因此你可以盡快把這些特性盡快地帶給新 MacBook Pro 的用戶。
在這個教程中羡铲,你學到了:
- 如何設置你的 app蜂桶,讓它能顯示 Touch Bar;
- 如何在 Touch Bar 里顯示靜止的 Label也切;
- 如何使用 binding(綁定)來添加一個動態(tài)的 Label扑媚;
- 如何在 Touch Bar 中添加控件腰湾,并處理它們的事件。
請不要在此停下疆股!NSTouchBar
和 NSTouchBarItem
中還有很多值得探索的特性费坊。你可以試著在 Touch Bar 里添加一個 Popover,或者也可以試試在你的 app 里格式化一個文本旬痹,你還可以在試著去在 Interface Builder 里創(chuàng)建一個 Touch Bar附井。