原文: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ā)生的事情:
- 你定義了一個(gè)可選的屬性類型為 Flight戴陡。這個(gè)類在 Flight.swift 中定義;
- 你添加了一個(gè)屬性觀察器,當(dāng)屬性設(shè)值時(shí)候會(huì)觸發(fā)它;
- 在可選屬性中確保有一個(gè)真的 flight 而不是 nil,當(dāng) flight 存在才會(huì)去設(shè)置 labels 的值;
- 使用 flight 的相關(guān)屬性去設(shè)置 labels
- 如果航班被延誤塞绿,那么你就將標(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)行討論簸搞!