[譯] 如何在 macOS 上使用 NSTouchBar

本文翻譯自 raywenderlich.comHow 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 提供的兩個類:NSTouchBarNSTouchBarItem(當然還有他們的子類)。

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

  • Slider:滑動調節(jié)某個值幸缕;
  • Popover:把更多功能藏入一個二級菜單中群发;
  • Color Picker:和名字一樣,用來選取顏色的咯???♀?发乔;
  • Custom:這個子類是你的天下熟妓,你可以在它的里面塞入文本、按鈕以及其他各種各樣的控件栏尚。

從文字大小顏色到圖片內容起愈,你可以隨意自定義你的 item,從而為你的用戶提供一個傳統(tǒng)鍵盤無法提供的抵栈、更加牛×的交互方式坤次,但是請時刻請謹記《人機交互則例》」啪ⅲ現(xiàn)在我們要開始動工啦。

準備開始

在開始敲代碼之前缰猴,請先點擊這里下載初始項目的源代碼产艾。

我們要編寫的 app 是一個簡單的旅行記錄 app。打開初始項目,如果你的設備不支持 Touch Bar闷堡,請點擊 Xcode 菜單欄上的 WindowShow 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,你將能看到兩個擴展定義了一些標識符: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
  }
}

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

  1. 創(chuàng)建一個新的 TouchBar 并設置它的 delegate;
  2. 設置 customizationIdentifier(自定義標識符)史侣,每個 TouchBarTouchBarItem 都需要一個獨一無二的標識符拴泌;
  3. 設置 Touch Bar 的默認 item 標識符,這將會告訴 Touch Bar 它將會容納哪些 item惊橱;
  4. 這一步是允許用戶可以自定義的 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

一步一步來看:

  1. 為「評分」新建了一個新的 label item耳标;
  2. 然后創(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

一步一步看:

  1. 和之前一樣闸盔,創(chuàng)建一個簡單的 Label;
  2. 創(chuàng)建另一個 Label橙凳,但這一次使用 bind 來把 Label 要顯示的文本綁定到一個屬性上蕾殴;
  3. 最后,創(chuàng)建一個 Segmented Control岛啸,并設置它的 action钓觉。你可以看到,為它設置一個 action 和其他常見控件是完全一樣的坚踩。

編譯并運行荡灾,除了 Scrubber,你現(xiàn)在還可以和 Segmented Control 交互了瞬铸。此外批幌,在 Touch Bar 里修改一個數(shù)值,app 的主窗口中也會顯示出來嗓节,反之亦然荧缘。

彩色按鈕

能讓用戶使用 Touch Bar 來進行「保存」操作是一個不錯的點子,因為這個按鈕和別的按鈕都不一樣拦宣,我們可以把它設置成綠色的截粗。你可以使用 NSButtonbezelColor 屬性來給它設置一個特殊的顏色。

打開 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 的用戶。

在這個教程中羡铲,你學到了:

  1. 如何設置你的 app蜂桶,讓它能顯示 Touch Bar;
  2. 如何在 Touch Bar 里顯示靜止的 Label也切;
  3. 如何使用 binding(綁定)來添加一個動態(tài)的 Label扑媚;
  4. 如何在 Touch Bar 中添加控件腰湾,并處理它們的事件。

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

How to Use NSTouchBar on macOS

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(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

推薦閱讀更多精彩內容

  • [譯] 零基礎 macOS 應用開發(fā)(二) 本文翻譯自 raywenderlich.com 的 macOS 開發(fā)經(jīng)...
    SR2k閱讀 3,634評論 1 3
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,161評論 25 707
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件状土、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,105評論 4 62
  • 李子+雞肉无蜂,還有一個不知名的涼性菜,這個六月的最后一周感受了斷食蒙谓,當然斥季,原因是拉肚子,第一天將近十次累驮,水狀酣倾,第二天...
    團的花園閱讀 270評論 0 0
  • 老家的藍天是具有獨特氣質的。天氣晴朗時碧空如洗谤专,藍的讓人陶醉躁锡,像是精美水粉畫;偶爾飄著幾多白云置侍,潔潤鮮柔稚铣,...
    寨泉閱讀 1,050評論 1 7