watchOS 2 教程(一):開(kāi)始吧

原文:watchOS 2 Tutorial Part 1: Getting Started

這一年的 WWDC 大會(huì)上,蘋(píng)果公司推出了 watchOS 2,這標(biāo)志著 Apple Watch 的開(kāi)發(fā)產(chǎn)生了巨大的變化。現(xiàn)在,你可以開(kāi)發(fā)能運(yùn)行在你手表上原生的 app 了凸舵。

在這篇 watchOS 2 教程中,你會(huì)開(kāi)發(fā)一個(gè)簡(jiǎn)單但是功能齊全的 watchOS 2 的 app。

在這個(gè)過(guò)程中,你會(huì)學(xué)到:

  • 如何為 iOS app 添加 watchOS 2 的 target
  • 如何在兩個(gè) target 之間共享數(shù)據(jù)
  • 如何添加一個(gè) watchOS 2 界面控制器到 storyboard,并放置界面對(duì)象
  • 如何創(chuàng)建 WKInterfaceController 的子類并連線
正式開(kāi)始吧

首先下載教程的起始項(xiàng)目吧哆档。

在Xcode中打開(kāi)它然后編譯運(yùn)行阅嘶。你應(yīng)該會(huì)看到一個(gè)空白界面:

這個(gè)項(xiàng)目沒(méi)有太多的文件,只包含一些你需要的最基本的文件。

添加 WatchKit App

選擇 File\New\Target… ,在出現(xiàn)的對(duì)話框中選擇 watchOS\Application\WatchKit App 然后點(diǎn)擊 Next:

在接下來(lái)的界面中,設(shè)置項(xiàng)目名字為 Watch,確保語(yǔ)言設(shè)置為 Swift,然后取消選中任何復(fù)選框。點(diǎn)擊 Finish:

之后會(huì)詢問(wèn)你是否想要激活 watch scheme,你需要這么做,所以確保選擇了激活:

祝賀,你剛剛創(chuàng)建了你的第一個(gè)手表 app!這真的很容易奕筐。

你會(huì)注意到,這個(gè)操作實(shí)際上創(chuàng)建了兩個(gè) target,而不是一個(gè),在項(xiàng)目導(dǎo)航中看到兩個(gè)對(duì)應(yīng)的組。這是因?yàn)槭直?app的代碼實(shí)際是作為一個(gè)擴(kuò)展形式存在的,類似 iOS 上的 Today extensions变骡。

當(dāng)你在項(xiàng)目導(dǎo)航中點(diǎn)開(kāi) Watch 和 Watch Extensions 組的時(shí)候,你會(huì)看到所有 storyboard 放在 Watch 組,當(dāng)前 target 創(chuàng)建的所有的類文件放在 Watch Extensions 組中:

你需要遵循如下的原則:任何你添加的代碼必須放在 Watch Extension 組中然后添加到 Watch Extension target,而所有的 assets 或者 storyboards 需要放在 Watch 組里救欧。

小家務(wù)

在繼續(xù)前,你需要?jiǎng)h掉一些 target 模板添加的你不需要的文件。

在項(xiàng)目導(dǎo)航中右鍵點(diǎn)擊 InterfaceController.swift 然后選擇刪除锣光。
當(dāng)彈出提示,選擇 Move to Trash 來(lái)確保文件確實(shí)從項(xiàng)目中刪掉了:

下一步,打開(kāi) Interface.storyboard,選擇其中僅有的界面控制器,按下 backspace 鍵來(lái)刪除它“实。現(xiàn)在就剩下一個(gè)空 storyboard,或者是我認(rèn)為的,一個(gè)空白畫(huà)布。

共享數(shù)據(jù)和代碼

起始項(xiàng)目包含一個(gè)記錄所有 Aber 航空公司航班信息的 JSON 文件,一個(gè)模型類表示飛行數(shù)據(jù)誊爹。這正是應(yīng)該共享的數(shù)據(jù),因?yàn)?iOS app 和手表 app 使用相同的模型類和數(shù)據(jù)-你記得 DRY (不要寫(xiě)重復(fù)的代碼)原則嗎?

在項(xiàng)目導(dǎo)航中點(diǎn)開(kāi) Shared 組然后選擇 Flights.json蹬刷。之后,在 File Inspector 中找到 Target Membership 區(qū)域,選中 Watch Extension:

文件現(xiàn)在應(yīng)該被 AirAber 和 Watch Extensions 這兩個(gè) target 所包含。
為其他 Shared 組的文件重復(fù)這個(gè)步驟,比如說(shuō) Flight.swift频丘。
這些都做完后,你可以開(kāi)始開(kāi)發(fā)航班詳情界面了!

構(gòu)造界面

打開(kāi) Watch\Interface.storyboard,從對(duì)象庫(kù)拖一個(gè)界面控制器到 storyboard 里面.選中這個(gè)界面控制器,打開(kāi)屬性檢查器設(shè)置它的 Identificer 為 Flight,然后勾選 Is Initial Controller:

你設(shè)置的這個(gè) Identifier 讓你可以在代碼中引用這個(gè)界面控制器办成。選中 Is Initial Controller 簡(jiǎn)單告訴 WatchKit 你希望當(dāng)應(yīng)用程序啟動(dòng)的時(shí)候首先顯示這個(gè)界面。

下一步,從對(duì)象庫(kù)中拖動(dòng)一個(gè)組到界面控制器:

之后這個(gè)組會(huì)包含 Aber 公司的 logo,航班號(hào)和路線搂漠。

選中這個(gè)組,在屬性檢查器的頂部改變它的 Insets 為 Custom迂卢。這會(huì)顯示四個(gè)額外的文本框讓你可以手動(dòng)的設(shè)置組的上下左右。設(shè)置 Top 為6:

這僅僅讓你的組到頂部有個(gè)額外的空隙。

下一步,拖動(dòng) Image 到組中而克。組會(huì)相應(yīng)的收縮來(lái)改變 Top inset (感謝 Xcode!),之后在文檔大綱中檢查來(lái)確保 Image 是組的子節(jié)點(diǎn),而不是同級(jí):

現(xiàn)在需要顯示一張圖片,下載 logo 圖片 然后把它拖動(dòng)到 Watch\Assets.xcassets 中靶壮。這會(huì)創(chuàng)建一個(gè)新的 logo 圖片,存放在2x的部分。

為了給圖片染色,選中這張圖片,在屬性檢查器中修改 Render As 為 Template Image员萍。

重新打開(kāi) Watch\Interface.storyboard 選中之前的 image.使用屬性檢查器,做如下的改變:

  • 設(shè)置圖片為 Logo - 當(dāng)下拉列表沒(méi)有出現(xiàn),你可以自己輸入;
  • 設(shè)置 Tint 為 #FA114F(也可以在顏色面板中輸入值);
  • 設(shè)置 Width 為 Fixed,值為40;
  • 設(shè)置 Height 為 Fixed,值為40腾降。

屬性檢查器現(xiàn)在應(yīng)該像下面這樣:

不要擔(dān)心看不到 logo,因?yàn)?Xcode 設(shè)計(jì)時(shí)無(wú)法給模板圖片染色!

下一步,往已經(jīng)存在的組中拖動(dòng)另外一個(gè)組,確保它出現(xiàn)在 image 的右側(cè),使用屬性檢查器設(shè)置 Layout 屬性為 Vertical.同樣修改 Spacing 為0、Width 為 Size to Fit Content碎绎。然后拖動(dòng)兩個(gè) label 到新的組中,放置一個(gè)到另一個(gè)的下面螃壤。

選擇上面的 label,使用屬性檢查器,設(shè)置文本為 Flight 123,文字顏色為 #FA114F。

選擇下面的 label,設(shè)置文本為 MAM to SFO筋帖。界面控制器最后看起來(lái)像下面這樣:

這些文本僅僅充當(dāng)占位符,之后會(huì)被控制器中設(shè)置的文本取代奸晴。

下一步,拖動(dòng)另一個(gè)組到界面控制器中,但是這次確保與第一個(gè)組同級(jí)。當(dāng)不能設(shè)置組級(jí)別關(guān)系請(qǐng)使用文檔大綱(Document Outline)日麸。

選中新的組,設(shè)置它的 Layout為 Vertical寄啼、Spacing 為0。

現(xiàn)在,拖動(dòng)三個(gè) label 到新的組中:

確保 label 都在 group 中,而不是與 group 同級(jí)!

選擇頂部的 label 使用屬性檢查器修改它的文本為 AA123 Boards赘淮。

選中中間的 label,修改文本顏色為 #FA114F,字體選擇 System,Regulaer 樣式和54.0的 size.最后,修改 Height 為 Fixed,值是44辕录。

選中底部的 label 修改文本為 On time,文本顏色為 #04DE71。

你的界面控制器應(yīng)該現(xiàn)在像下面這樣:

從對(duì)象庫(kù)中拖動(dòng)一個(gè)新的組到下面的組,這次確保它是在子節(jié)點(diǎn)而不是在同級(jí),之后向其中添加兩個(gè) label,你完全的界面對(duì)象關(guān)系應(yīng)該像這樣:

使用屬性檢查器,設(shè)置左邊的 label 文本為 Gate 1A梢卸。右邊的 label 設(shè)置為 Seat 64A,之后設(shè)置它的 Horizontal alignment 為 Right

完全的界面應(yīng)該像如下這樣:

恭喜,你已經(jīng)完成你的第一個(gè) watch app 界面的布局了,現(xiàn)在是時(shí)候給它填充一些真實(shí)的數(shù)據(jù)然后在模擬器上運(yùn)行走诞。

創(chuàng)建控制器

在項(xiàng)目導(dǎo)航中右擊 Watch Extensions 組,選擇 New File,在出現(xiàn)的對(duì)話框中選擇 watchOS\Source\WatchKit Class 然后點(diǎn)擊 Next。命名新的類為 FlightInterfaceController ,確保它為 WKInterfaceController 的子類,語(yǔ)言設(shè)置為 Swift:

點(diǎn)擊 Next,之后是 Create

可以看到新的文件在代碼編輯器中打開(kāi)了,刪除其中的三個(gè)空方法,只剩下 import 語(yǔ)句和類定義蛤高。

添加這些 outlets 到 FlightInterfaceController 的頂部:

@IBOutlet var flightLabel: WKInterfaceLabel!
@IBOutlet var routeLabel: WKInterfaceLabel!
@IBOutlet var boardingLabel: WKInterfaceLabel!
@IBOutlet var boardTimeLabel: WKInterfaceLabel!
@IBOutlet var statusLabel: WKInterfaceLabel!
@IBOutlet var gateLabel: WKInterfaceLabel!
@IBOutlet var seatLabel: WKInterfaceLabel!

這里僅僅為之前的每個(gè) label 添加一個(gè) Outlet蚣旱。稍后會(huì)把他們連接起來(lái)。

下一步,在 outlets 下面添加 flight 屬性和對(duì)應(yīng)的屬性觀察器:

// 1
var flight: Flight? {
  // 2
  didSet {
    // 3
    if let flight = flight {
      // 4
      flightLabel.setText("Flight \(flight.shortNumber)")
      routeLabel.setText(flight.route)
      boardingLabel.setText("\(flight.number) Boards")
      boardTimeLabel.setText(flight.boardsAt)
      // 5
      if flight.onSchedule {
        statusLabel.setText("On Time")
      } else {
        statusLabel.setText("Delayed")
        statusLabel.setTextColor(UIColor.redColor())
      }
      gateLabel.setText("Gate \(flight.gate)")
      seatLabel.setText("Seat \(flight.seat)")
    }
  }
}

一步步講解發(fā)生的事情:

  1. 你定義了一個(gè)可選的屬性類型為 Flight戴陡。這個(gè)類在 Flight.swift 中定義;
  2. 你添加了一個(gè)屬性觀察器,當(dāng)屬性設(shè)值時(shí)候會(huì)觸發(fā)它;
  3. 在可選屬性中確保有一個(gè)真的 flight 而不是 nil,當(dāng) flight 存在才會(huì)去設(shè)置 labels 的值;
  4. 使用 flight 的相關(guān)屬性去設(shè)置 labels
  5. 如果航班被延誤塞绿,那么你就將標(biāo)簽的文本顏色改為紅色

在控制器第一次顯示時(shí)候設(shè)置航班。添加以下聲明:

override func awakeWithContext(context: AnyObject?) {
  super.awakeWithContext(context)
  flight = Flight.allFlights().first!
}

本后面的教程會(huì)修改為在上下文中傳遞值給它,但現(xiàn)在你只需要從共享的 JSON 文件中加載所有的航班,然后使用數(shù)組中的第一個(gè)恤批。

在后面的教程你將學(xué)到更多關(guān)于 awakeWithContext(_:) 的知識(shí),但是現(xiàn)在你僅僅需要知道它是界面控制器生命周期第一環(huán)節(jié),一個(gè)設(shè)置 flight 值的地方异吻。

現(xiàn)在僅剩最后一步你就可以編譯運(yùn)行了,就是去連接 outlets

連接outlets

打開(kāi) Watch\Interface.storyboard 選擇界面控制器,使用 Identity Inspector,設(shè)置 Class\Custom Class 為 FlightInterfaceController

下一步,右擊界面控制器頂部的黃色圖片彈出窗口:

現(xiàn)在,按下面的列表連接 outlets:

boardingLabel: AA123 Boards
boardTimeLabel: 15:06
flightLabel: Flight 123
gateLabel: Gate 1A
routeLabel: MAN to SFO
seatLabel: Seat 64A
statusLabel: On time

在運(yùn)行之前,有一件事情要做。本教程的實(shí)例 app 專為42mm 的 Apple Watch 開(kāi)發(fā)的,所以你需要確保正確設(shè)置了模擬器,否則界面元素看起來(lái)會(huì)有點(diǎn)小喜庞。對(duì)于一個(gè)現(xiàn)實(shí) app,需要確保界面能很好運(yùn)行在兩種大小的手表上,但這在本教程的范圍之外诀浪。

在 Xcode 中,選擇 Window\Devices 打開(kāi)設(shè)備管理器,點(diǎn)擊右下角的 + 圖標(biāo).在彈出的對(duì)話框中,命名模擬器為 iPhone 6 - 42mm,設(shè)置設(shè)備類型為 iPhone 6,修改配對(duì)的 Apple watch 為 Apple Watch – 42mm (WatchOS 2.0) 然后點(diǎn)擊 Create:

關(guān)閉設(shè)備管理器,選擇 Watch Scheme,然后選中新的模擬器:

編譯運(yùn)行。一段模擬器啟動(dòng)完成你會(huì)看到下面界面:

注意:如果收到一條錯(cuò)誤消息,說(shuō)明安裝失敗,然后你可以再次嘗試使用 Xcode,或者在手表模擬器上手動(dòng)安裝 app延都。為此,打開(kāi) iOS 模擬器中的手表 app,點(diǎn)擊 AirAber ,在 Apple Watch 彈出我們的 app雷猪。一旦這么做了,返回手表模擬器,按 Shift + Ctrl + H 導(dǎo)航到主界面, 然后點(diǎn)擊 AirAber 圖片來(lái)啟動(dòng)手表 app。

恭喜!你已經(jīng)完成 WatchKit 初始界面,并使用真實(shí)的數(shù)據(jù)使它很好運(yùn)行在手表模擬器上晰房。

接下來(lái)做什么?

下面是這個(gè)系列教程完整示例項(xiàng)目求摇。

在這個(gè)練習(xí)中你已經(jīng)學(xué)會(huì)了如何往現(xiàn)有的 iOS app 中添加手表 app射沟,如何創(chuàng)建一個(gè)界面控制器和使用嵌套組構(gòu)造一個(gè)非常復(fù)雜的界面,以及使用 WKInterfaceController 類來(lái)配合這項(xiàng)工作与境。那么验夯,接下來(lái)呢?

本教程系列的第二部分嚷辅,你將學(xué)習(xí)所有關(guān)于表和導(dǎo)航 WatchKit 的使用簿姨。

如果您對(duì)本教程有任何疑問(wèn)或意見(jiàn)距误,請(qǐng)參加下面的論壇進(jìn)行討論簸搞!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市准潭,隨后出現(xiàn)的幾起案子趁俊,更是在濱河造成了極大的恐慌,老刑警劉巖刑然,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寺擂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡泼掠,警方通過(guò)查閱死者的電腦和手機(jī)怔软,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)择镇,“玉大人挡逼,你說(shuō)我怎么就攤上這事∧逋悖” “怎么了家坎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吝梅。 經(jīng)常有香客問(wèn)我虱疏,道長(zhǎng),這世上最難降的妖魔是什么苏携? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任做瞪,我火速辦了婚禮,結(jié)果婚禮上右冻,老公的妹妹穿的比我還像新娘装蓬。我一直安慰自己,他們只是感情好国旷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布矛物。 她就那樣靜靜地躺著,像睡著了一般跪但。 火紅的嫁衣襯著肌膚如雪履羞。 梳的紋絲不亂的頭發(fā)上峦萎,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音忆首,去河邊找鬼爱榔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛糙及,可吹牛的內(nèi)容都是我干的详幽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼浸锨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼唇聘!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起柱搜,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤迟郎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后聪蘸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體宪肖,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年健爬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了控乾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娜遵,死狀恐怖蜕衡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情魔熏,我是刑警寧澤衷咽,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站蒜绽,受9級(jí)特大地震影響镶骗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躲雅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一鼎姊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧相赁,春花似錦相寇、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绵脯,卻和暖如春佳励,著一層夾襖步出監(jiān)牢的瞬間休里,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工赃承, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妙黍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓瞧剖,卻偏偏與公主長(zhǎng)得像拭嫁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抓于,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容