[譯] 如何在 macOS 上使用 NSTouchBar

本文翻譯自 raywenderlich.comHow to Use NSTouchBar on macOS,已咨詢對(duì)方網(wǎng)站,可至多翻譯 10 篇文章。
各位若有英語(yǔ)閱讀能力的話,還是先打賞然后去閱讀英文原吧??。
綜上,此翻譯版本僅供參考,謝絕轉(zhuǎn)載。

也歡迎你點(diǎn)擊我的頭像查看我翻譯的其他 macOS 開發(fā)教程??

對(duì)了我跟著這個(gè)教程敲代碼的時(shí)候發(fā)現(xiàn)文中所有的 @available(OSX 10.12.1, *) 其實(shí)應(yīng)為 @available(OSX 10.12.2, *),但是出于對(duì)原文的尊重沒(méi)有修改,請(qǐng)各位注意~

等了好久好久終于等到今天之后,Apple 終于發(fā)布了新款的 MacBook Pro,它最惹人矚目的應(yīng)該就是那塊(小小的)觸屏了吧。

新款設(shè)備用全新的 Touch Bar 替代了原有的功能鍵,它們可擴(kuò)展、支持多點(diǎn)觸控,更重要的是,Touch Bar 對(duì)開發(fā)者們完全開放,這意味著你的 macOS app 可以獲得一種全新的交互方式。

如果你是一個(gè) macOS 開發(fā)者,你一定很希望自己的 app 能夠立刻使用上這項(xiàng)前沿科技。在這個(gè)教程中,我會(huì)將向你們展示如何使用全新的 NSTouchBar API 來(lái)為你的 macOS app 創(chuàng)建一個(gè)動(dòng)態(tài)的 Touch Bar。

注意:這個(gè)教程需要 Xcode 8.1 或更高版本以及 macOS 10.12.1 (Build 16B2657) 或更高版本,否則的話你將無(wú)法運(yùn)行 Touch Bar 模擬器。你可以在 ?關(guān)于本機(jī)里點(diǎn)擊數(shù)字版本號(hào)來(lái)查看 build 版本。


如果你的版本不夠,你可以在 Apple 的網(wǎng)站上 下載。

Touch Bar 是個(gè)啥?

如上文所述,Touch Bar 是一塊安裝在鍵盤上方的細(xì)長(zhǎng)形的觸摸屏,它允許用戶使用一種全新的方式來(lái)與 app(以及 Mac)進(jìn)行交互。

在 Touch Bar 上有三個(gè)默認(rèn)的部分:

  • 系統(tǒng)按鈕:根據(jù)運(yùn)行的 app,這里將會(huì)顯示一個(gè)系統(tǒng)級(jí)的按鈕,比如 esc;
  • App 區(qū)域:你的 app 可以控制的顯示區(qū)域,也就是我們的主舞臺(tái);
  • 控制條:這里用于顯示你熟悉的控制按鈕,比如亮度、音量等。

和其它許多 Apple 的新科技一樣,Touch Bar 也擁有自己的《人機(jī)交互則例(Human Interface Guidelines)》,為了你的 app 和其它 Mac app 擁有統(tǒng)一的用戶體驗(yàn),你應(yīng)當(dāng)遵循這份則例。你可以點(diǎn)擊這里閱讀它。

概括說(shuō)來(lái),這份則例中比較重要的幾點(diǎn)有:

  • App 中的某個(gè)功能不應(yīng)該只能在 Touch Bar 中使用:即使部份用戶還未升級(jí)到最新的硬件,你的 app 也應(yīng)該盡量為他們提供一樣的功能。如果你決定為 Touch Bar 加入某些功能,請(qǐng)確保這個(gè)功能也能在 app 的其他某處也可以訪問(wèn)到。另外 Touch Bar 是可以被用戶禁用的,所以也別太指望你的用戶能一直看到它;
  • Touch Bar 是鍵盤的延伸,而不是一個(gè)顯示屏:誠(chéng)然,Touch Bar 是一個(gè)顯示屏,但是它不是顯示器的延伸,而是一個(gè)與 app 交互的窗口。你不應(yīng)該在 Touch Bar 上用滾來(lái)滾去的內(nèi)容或 blingbling 的警告打擾用戶的視線;
  • 快速響應(yīng):用戶在鍵盤上按下一個(gè)真實(shí)的按鍵時(shí),按鍵會(huì)立即給予一個(gè)反饋(也就是被按下去了)。同理,用戶在 Touch Bar 上按下一個(gè)虛擬按鈕時(shí),你也應(yīng)該給他們提供即時(shí)的反饋。

如何讓你的 app 支持 Touch Bar

要讓你的 app 支持 Touch Bar,你需要使用 Apple 提供的兩個(gè)類:NSTouchBarNSTouchBarItem(當(dāng)然還有他們的子類)。

某些 NSTouchBarItem 的子類提供了這些功能:

  • Slider:滑動(dòng)調(diào)節(jié)某個(gè)值;
  • Popover:把更多功能藏入一個(gè)二級(jí)菜單中;
  • Color Picker:和名字一樣,用來(lái)選取顏色的咯???♀?;
  • Custom:這個(gè)子類是你的天下,你可以在它的里面塞入文本、按鈕以及其他各種各樣的控件。

從文字大小顏色到圖片內(nèi)容,你可以隨意自定義你的 item,從而為你的用戶提供一個(gè)傳統(tǒng)鍵盤無(wú)法提供的、更加牛×的交互方式,但是請(qǐng)時(shí)刻請(qǐng)謹(jǐn)記《人機(jī)交互則例》?,F(xiàn)在我們要開始動(dòng)工啦。

準(zhǔn)備開始

在開始敲代碼之前,請(qǐng)先點(diǎn)擊這里下載初始項(xiàng)目的源代碼。

我們要編寫的 app 是一個(gè)簡(jiǎn)單的旅行記錄 app。打開初始項(xiàng)目,如果你的設(shè)備不支持 Touch Bar,請(qǐng)點(diǎn)擊 Xcode 菜單欄上的 WindowShow Touch Bar,Touch Bar 的模擬器就會(huì)出現(xiàn)在屏幕上。

編譯并運(yùn)行你的 app,你將會(huì)看到 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
  }
}

這些代碼將會(huì)幫你搞定啟用 Touch Bar 所需要的各種操作,(在寫這篇文章的時(shí)候)Xcode 還沒(méi)有 macOS 10.12.1 的配套 SDK,所以你需要在 Touch Bar 相關(guān)的代碼周邊添加 #available(OS X 10.12.1, *),當(dāng)然如果你忘了這件事,Xcode 會(huì)給你一個(gè)溫馨的提醒??。

打開 WindowController.swift,找到 makeTouchBar(),這個(gè)方法用于檢測(cè) ViewController 是否含有一個(gè)可以被返回的 Touch Bar,如果有,它會(huì)把這個(gè) Touch Bar 返回給 Window,然后呈現(xiàn)給用戶?,F(xiàn)在,我們還沒(méi)有創(chuàng)建 Touch Bar,所以什么也不會(huì)發(fā)生。

在你開始創(chuàng)建自己的 Touch Bar 和 Touch Bar Item 之前,你需要注意這些類都需要獨(dú)一無(wú)二的 identifier(標(biāo)識(shí)符),打開 TouchBarIdentifiers.swift,你將能看到兩個(gè)擴(kuò)展定義了一些標(biāo)識(shí)符:NSTouchBarCustomizationIdentifierNSTouchBarItemIdentifier。

前往 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
  }
}

在此處,通過(guò)重寫 makeTouchBar() 方法,你給你的 View 或 Window 創(chuàng)建了一個(gè) Touch Bar,在這個(gè)方法中:

  1. 創(chuàng)建一個(gè)新的 TouchBar 并設(shè)置它的 delegate;
  2. 設(shè)置 customizationIdentifier(自定義標(biāo)識(shí)符),每個(gè) TouchBarTouchBarItem 都需要一個(gè)獨(dú)一無(wú)二的標(biāo)識(shí)符;
  3. 設(shè)置 Touch Bar 的默認(rèn) item 標(biāo)識(shí)符,這將會(huì)告訴 Touch Bar 它將會(huì)容納哪些 item;
  4. 這一步是允許用戶可以自定義的 item。作為參考,你可以打開 Finder,點(diǎn)擊菜單欄上的 顯示自定 Multi-Touch Bar看看自定義 Touch Bar 是什么效果。

接下來(lái),我們還需要設(shè)置 .infoLabelItem 是什么樣子的,在同一個(gè) 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
    }
}

通過(guò)實(shí)現(xiàn)touchBar(_:makeItemForIdentifier:) 方法,你可以自定義你的 Touch Bar Item,在段代碼里,你創(chuàng)建了一個(gè) NSCustomTouchBarItem,并把它的 view 設(shè)置為了 NSTextField

編譯并運(yùn)行你的 app,你可以看到 Touch Bar 多了一個(gè) item。

耶??!通過(guò)一番努力你得到了……兩個(gè) emoji…好吧,現(xiàn)在我們來(lái)添加一些別的控件。

Text Field 和 Scrubber

makeTouchBar() 里,把 touchBar.defaultItemIdentifiers = [.infoLabelItem] 修改為:

touchBar.defaultItemIdentifiers = [.infoLabelItem, .flexibleSpace, .ratingLabel, .ratingScrubber]

這些代碼會(huì)讓 Touch Bar 顯示三個(gè) item:一個(gè) label、一個(gè) scrubber 以及一個(gè) .flexibleSpace。這是一個(gè)動(dòng)態(tài)的間距,它可以把各種 item 按組進(jìn)行整潔的分類。此外你還可以使用 .fixedSpaceSmall.fixedSpaceLarge 這兩個(gè)固定間距。

和之前的那個(gè) 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

一步一步來(lái)看:

  1. 為「評(píng)分」新建了一個(gè)新的 label item;
  2. 然后創(chuàng)建一個(gè)新的 item 用來(lái)展示 NSScrubber。這是一個(gè) Touch Bar 特有的控件,它允許你在若干個(gè)項(xiàng)目中進(jìn)行選擇。Scrubber 需要一個(gè)代理來(lái)處理事件,你需要做的是設(shè)置一個(gè) delegate(初始項(xiàng)目的源代碼已經(jīng)在 ViewController 里實(shí)現(xiàn)過(guò)這個(gè)協(xié)議了)。

編譯并運(yùn)行你的 app,你將會(huì)看到 Touch Bar 里多出了兩個(gè)新的 item,當(dāng)你點(diǎn)擊某個(gè) scrubber 里的項(xiàng)目后,在 app 的主窗口里能看到數(shù)值的調(diào)整。

Segmented Control

接下來(lái),我們來(lái)添加一個(gè) Segmented Control。這個(gè)控件沒(méi)有使用 Delegate 模式,因此這剛好可以讓你體驗(yàn)一下怎么設(shè)置 Touch Bar 里的 Target-Action(目標(biāo)動(dòng)作)?;氐?makeTouchBar() 中,把這三個(gè) item 添加到 defaultItemIdentifiers 里:

touchBar.defaultItemIdentifiers = [.infoLabelItem, .flexibleSpace, .ratingLabel, .ratingScrubber, .flexibleSpace, .visitedLabelItem, .visitedItem, .visitSegmentedItem]

以及把最后的三個(gè) 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

一步一步看:

  1. 和之前一樣,創(chuàng)建一個(gè)簡(jiǎn)單的 Label;
  2. 創(chuàng)建另一個(gè) Label,但這一次使用 bind 來(lái)把 Label 要顯示的文本綁定到一個(gè)屬性上;
  3. 最后,創(chuàng)建一個(gè) Segmented Control,并設(shè)置它的 action。你可以看到,為它設(shè)置一個(gè) action 和其他常見控件是完全一樣的。

編譯并運(yùn)行,除了 Scrubber,你現(xiàn)在還可以和 Segmented Control 交互了。此外,在 Touch Bar 里修改一個(gè)數(shù)值,app 的主窗口中也會(huì)顯示出來(lái),反之亦然。

彩色按鈕

能讓用戶使用 Touch Bar 來(lái)進(jìn)行「保存」操作是一個(gè)不錯(cuò)的點(diǎn)子,因?yàn)檫@個(gè)按鈕和別的按鈕都不一樣,我們可以把它設(shè)置成綠色的。你可以使用 NSButtonbezelColor 屬性來(lái)給它設(shè)置一個(gè)特殊的顏色。

打開 TouchBarIdentifiers.swift,在 NSTouchBarItemIdentifier extension 里,添加這些代碼:

static let saveItem = NSTouchBarItemIdentifier("com.razeware.SaveItem")

這將會(huì)從頭開始創(chuàng)建一個(gè)標(biāo)識(shí)符,以此允許你在 Touch Bar 里添加一個(gè) item。

返回 ViewController.swift,添加一個(gè)新的 .flexSpace.saveItem 到 Touch Bar 的 defaultItemIdentifiers 里:

touchBar.defaultItemIdentifiers = [.infoLabelItem, .flexibleSpace, .ratingLabel, .ratingScrubber, .flexibleSpace, .visitedLabelItem, .visitedItem, .visitSegmentedItem, .flexibleSpace, .saveItem]

基本上完成了,最后一步是對(duì)按鈕進(jìn)行一些設(shè)置。在 touchBar(_:makeItemForIdentifier:) 中添加最后一個(gè) 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

通過(guò) bezelColor,你已經(jīng)把這個(gè)按鈕成功地修改成了綠色。

編譯并運(yùn)行,你會(huì)看到 Touch Bar 上有了一個(gè)綠色的按鈕,它和窗口中的 Save 按鈕擁有一樣的功能。

現(xiàn)在該做些啥?

你可以點(diǎn)擊這里下載最終完成的項(xiàng)目。

這些就是 Touch Bar 的基礎(chǔ)了。顯然,Apple 希望 Touch Bar 的開發(fā)過(guò)程越簡(jiǎn)單越好,因此你可以盡快把這些特性盡快地帶給新 MacBook Pro 的用戶。

在這個(gè)教程中,你學(xué)到了:

  1. 如何設(shè)置你的 app,讓它能顯示 Touch Bar;
  2. 如何在 Touch Bar 里顯示靜止的 Label;
  3. 如何使用 binding(綁定)來(lái)添加一個(gè)動(dòng)態(tài)的 Label;
  4. 如何在 Touch Bar 中添加控件,并處理它們的事件。

請(qǐng)不要在此停下!NSTouchBarNSTouchBarItem 中還有很多值得探索的特性。你可以試著在 Touch Bar 里添加一個(gè) Popover,或者也可以試試在你的 app 里格式化一個(gè)文本,你還可以在試著去在 Interface Builder 里創(chuàng)建一個(gè) Touch Bar。

How to Use NSTouchBar on macOS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • [譯] 零基礎(chǔ) macOS 應(yīng)用開發(fā)(二) 本文翻譯自 raywenderlich.com 的 macOS 開發(fā)經(jīng)...
    SR2k閱讀 3,698評(píng)論 1 3
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,036評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,315評(píng)論 4 61
  • 李子+雞肉,還有一個(gè)不知名的涼性菜,這個(gè)六月的最后一周感受了斷食,當(dāng)然,原因是拉肚子,第一天將近十次,水狀,第二天...
    團(tuán)的花園閱讀 342評(píng)論 0 0
  • 老家的藍(lán)天是具有獨(dú)特氣質(zhì)的。天氣晴朗時(shí)碧空如洗,藍(lán)的讓人陶醉,像是精美水粉畫;偶爾飄著幾多白云,潔潤(rùn)鮮柔,...
    寨泉閱讀 1,109評(píng)論 1 7

友情鏈接更多精彩內(nèi)容