watchOS 2 教程(二):列表

原文:watchOS 2 Tutorial Part 2: Tables

歡迎回到 watchOS 2 系列教程!

在第一部分,你通過開發(fā)第一個(gè)界面控制器,學(xué)習(xí)了 watchOS 2 開發(fā)的基礎(chǔ)知識(shí)坯临。

在教程的第二部分,會(huì)向你的 app 添加一個(gè) table 來展示航班列表沪曙。

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

如何添加一個(gè)新的界面控制器,往控制器中添加一個(gè) table,并且設(shè)計(jì)原型行扶踊。

如何創(chuàng)建 WKInterfaceController 的子類來填充這個(gè)列表,配置每一行的數(shù)據(jù),并且處理選中事件;

如何模態(tài)呈現(xiàn)界面控制器和向它傳遞數(shù)據(jù)來顯示雇寇。

介紹了這些,讓我們正式開始吧!

開始

打開 Watch\Interface.storyboard,從對(duì)象庫中拖動(dòng)另一個(gè)界面控制器到 storyboard 畫板中,放在已經(jīng)存在的航班控制器的左邊魄缚。

選中新的界面控制器,打開屬性檢查器然后做如下修改:

設(shè)置 Identifier 為 Schedule;

設(shè)置 Title 為 Air Aber;

勾選 Is Inital Controller;

勾選 Display Activity Indicator When Loading

你會(huì)注意到截圖的標(biāo)題是深灰色的,而不是充滿活力的粉紅色君丁。讓我們解決它锨亏。

打開文件檢查器然后改變 Globla Tint 為 #FA114F。現(xiàn)在看起來更好一點(diǎn)了:

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

在文本大綱中選中 Table Row Controller:

使用屬性檢查器設(shè)置它的 Identifier 為 FlightRow棵癣。使用 identifier 作為行的類型標(biāo)示來通知列表哪一行應(yīng)該被實(shí)例化,它非常重要,所以需要你去設(shè)置。

設(shè)計(jì)行界面

首先修改行提供的默認(rèn)布局夺衍。從文檔大綱中選擇 table row 中的組,使用屬性檢查器設(shè)置組的 Spacing 為6狈谊、Height 為 Size To Fit Content。

table row 默認(rèn)有個(gè)標(biāo)準(zhǔn)沟沙、固定的高度河劝。然而,大多數(shù)時(shí)候你會(huì)希望能顯示全部添加進(jìn)去的界面元素,所以總是值得使用這種方式去修改高度屬性。

將一個(gè)分隔線從對(duì)象庫中拖到行中矛紫。你不會(huì)真的用它去分割什么,而是向你的行里添加一點(diǎn)視覺上的間隔赎瞎。選中分割線,使用屬性檢查器做如下修改:

設(shè)置 Color 為 #FA114F;

設(shè)置 Vertical alignment 為 Center;

設(shè)置 Height 為 Relative to Container;

設(shè)置 Adjustment 為-4。

最后檢查器應(yīng)該是這樣:

現(xiàn)在是時(shí)候填充這一行了!

從對(duì)象庫中拖一個(gè)Group到到 table row 中,放在分割線的后面颊咬。選中組,在屬性檢查器中修改如下屬性:

設(shè)置 Layout 為 Vertical;

設(shè)置 Spacing 為0;

設(shè)置 Width 為 Size To Fit Content务甥。

你可能注意到你經(jīng)常設(shè)置的 Spacing 屬性;它的作用僅僅是收緊組中的界面元素之間的間距讓它們?cè)谛∑聊簧峡雌饋砀逦?/p>

拖動(dòng)另一個(gè) Group 到剛才添加的組中,做如下改變:

設(shè)置 Spacing 為4;

設(shè)置 Height 為 Fixed,值為32。

往這個(gè)新的組中,添加一個(gè) Label喳篇、一個(gè) Image然后另一個(gè) Label敞临。這兩個(gè)標(biāo)簽會(huì)顯示每個(gè)航班的起點(diǎn)和重點(diǎn)。

現(xiàn)在你需要往 image 中添加圖片麸澜。下載圖片然后把它添加到 Watch\Assets.xcassets 中挺尿。這次創(chuàng)建一個(gè)新的叫做Plane的圖片,放在2x槽中:

重新打開 Watch\Interface.storyboard 然后選擇這個(gè) image。使用屬性檢查器,做如下改變:

設(shè)置 Image 為 Plane;

設(shè)置 Tint 為 #FA114F;

設(shè)置 Vertical alignment 為 Center;

設(shè)置 Width 為 Fixed,值為24;

設(shè)置 Height 為 Fixed,值為20炊邦。

選擇左邊的標(biāo)簽設(shè)置它的文本為 MAN编矾。修改它的 Font 為 System, style 為 Semibold 和20的字體大小。最后設(shè)置它的 Vertical alignment 為 Center铣耘。

同樣修改右邊的標(biāo)簽,但是文本修改成 SFO洽沟。你的 table row 現(xiàn)在應(yīng)該是這樣:

界面元素層次結(jié)構(gòu)像下面這樣:

你已經(jīng)完成大多數(shù) table row 界面的設(shè)計(jì);之后需要增加航班號(hào)和狀態(tài)了。

從對(duì)象庫中拖動(dòng)另一個(gè) Group 到 table row ,確保它是包含起點(diǎn)終點(diǎn)標(biāo)簽的那個(gè)組的子節(jié)點(diǎn):

當(dāng)你繼續(xù)設(shè)計(jì)這個(gè)界面,你可以看到更多使用嵌套組與混合布局來創(chuàng)建復(fù)雜布局的例子蜗细。根本就沒自動(dòng)布局的事裆操。

拖動(dòng)兩個(gè) label 到新的組中。再次使用屬性檢查器對(duì)最左邊的標(biāo)簽做如下的改變:

設(shè)置 Text 為 AA123;

設(shè)置 Text Color 為 Light Gray Color;

設(shè)置 Font 為 Caption 2;

設(shè)置 Vertical alignment 為 Bottom炉媒。

修改右邊的標(biāo)簽:

設(shè)置 Text 為 On time;

設(shè)置 Text Color 為 #04DE71;

設(shè)置 Font 為 Caption 2;

設(shè)置 Horizontal alignment 為 Right;

設(shè)置 Vertical alignment 為 Bottom踪区。

做完這些改變后,最后的 table row 看起來應(yīng)該像這樣:

列表在 Interface Builder 中開發(fā)完成,是時(shí)候填充一些數(shù)據(jù)了。

填充列表

首先創(chuàng)建一個(gè) WKInterfaceController 的子類為列表提供數(shù)據(jù)吊骤。

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

點(diǎn)擊 Next,然后 Create白粉。

當(dāng)在代碼編輯器中打開了新創(chuàng)建的文件,刪除三個(gè)空的方法后就剩下重要的語句和類定義了传泊。

重新打開 Watch\Interface.storyboard ,選擇新的界面控制器鼠渺。在 Identity Inspector,修改 Custom Class\Class 為 ScheduleInterfaceController:

在選中界面控制器的基礎(chǔ)上,打開輔助編輯器確保它顯示的是 ScheduleInterfaceController。然后按住 Ctrl從 Table 往 ScheduleInterfaceController 里面拖拽來創(chuàng)建一個(gè) outlet:

命名 outlet 為 flightTable,確保類型設(shè)置為 WKInterfaceTable 然后點(diǎn)擊 Connect眷细。

現(xiàn)在你已經(jīng)設(shè)置好自定義的類并且為 table 創(chuàng)建了一個(gè) outlet,是時(shí)候填充一些數(shù)據(jù)了!

關(guān)閉輔助編輯器,打開 ScheduleInterfaceController.swift,在 outlet 的下面添加如下代碼

varflights = Flight.allFlights()

這里你僅僅增加了一個(gè) Flight 對(duì)象數(shù)組保存所有航班信息拦盹。

下一步,增加 awakeWithContext(_:) 的實(shí)現(xiàn):

override funcawakeWithContext(context: AnyObject?){super.awakeWithContext(context)? flightsTable.setNumberOfRows(flights.count, withRowType:"FlightRow")}

這段代碼通知 table 為 flights 數(shù)組中每個(gè) flight 創(chuàng)建一個(gè) Interface Builder 中的行實(shí)例。行的數(shù)量等于數(shù)組的大小,行的類型就是你在 storyboard 中設(shè)置的 identifier 的值溪椎。

編譯運(yùn)行普舆。你會(huì)看到列表已經(jīng)填充幾行數(shù)據(jù)了:

你應(yīng)該注意到列表中顯示的是 Interface Builder 中的占位文本。為了修復(fù)這種情況,我們通過添加 row controller 分別配置每一行的 label校读。

添加 Row Controller

在項(xiàng)目導(dǎo)航中右擊 Watch Extension 組然后選擇 New File...沼侣。在出現(xiàn)的對(duì)話框中選擇 watchOS\Source\WatchKit Class 然后點(diǎn)擊 Next。命名新的類為 FlightRowContorller,確保這個(gè)類是 NSObject 的子類并且語言設(shè)置為 Swift 了:

點(diǎn)擊 Next,之后 Create歉秫。

當(dāng)新的文件在代碼編輯器中打開了,在類的頂部增加如下代碼:

@IBOutletvar separator: WKInterfaceSeparator!@IBOutletvar originLabel: WKInterfaceLabel!@IBOutletvar destinationLabel: WKInterfaceLabel!@IBOutletvar flightNumberLabel: WKInterfaceLabel!@IBOutletvar statusLabel: WKInterfaceLabel!@IBOutletvar planeImage: WKInterfaceImage!

這里僅僅為每個(gè)你添加到 table row 中的 label 添加對(duì)應(yīng)的 outlet蛾洛。稍后會(huì)連接它們。

下一步,在這些 outlet 下面添加如下這個(gè)屬性和對(duì)應(yīng)的屬性監(jiān)視器:

// 1varflight: Flight? {// 2didSet {// 3ifletflight = flight {// 4originLabel.setText(flight.origin)? ? ? destinationLabel.setText(flight.destination)? ? ? flightNumberLabel.setText(flight.number)// 5ifflight.onSchedule {? ? ? ? statusLabel.setText("On Time")? ? ? }else{? ? ? ? statusLabel.setText("Delayed")? ? ? ? statusLabel.setTextColor(UIColor.redColor())? ? ? }? ? }? }}

下面一步步講解是怎么回事:

你定義了類型為 Flight 的可選屬性端考。記住,這個(gè)類是在 Flight.swift 中定義的,而 Flight.swift 是你在教程1中添加到 Watch Extension 中的共享代碼的一部分;

添加了一個(gè)屬性監(jiān)視器,當(dāng)屬性被賦值的時(shí)候會(huì)觸發(fā);

當(dāng) flight 為 nil 的時(shí)候會(huì)提前退出雅潭。因?yàn)樗强蛇x的,只有當(dāng) Flight 對(duì)象有效的時(shí)候才去設(shè)置標(biāo)簽的屬性。

使用 flight 的相關(guān)屬性去設(shè)置標(biāo)簽却特。

如果航班被延誤了,改變標(biāo)簽的文本顏色,并相應(yīng)地更新文本扶供。

當(dāng) row controller 設(shè)置完成,現(xiàn)在需要更新 table row 來使用它。

打開 Watch\Interface.storyboard 然后在文檔大綱中選擇 FlightRow裂明。使用 Identity Inspector,設(shè)置 Custom Class\Class 為 FlightRowController椿浓。

下一步,在文檔大綱中右擊FlightRow:

連接 planeImage 和 table row 中的 image,separator 與 table row 中的 separator。之后進(jìn)行如下連線:

destinationLabel: SFO

flightNumberLabel: AA123

originLabel: MAN

statusLabel: On time

最后一步就是更新 ScheduleInterfaceController 來向列表中每個(gè)行控制器傳遞 Flight 對(duì)象闽晦。

打開 ScheduleInterfaceController.swift 之后在 awakeWithContext(_:) 底下添加如下代碼:

forindexin0..

這里使用 for 循環(huán)遍歷列表中每一行來訪問指定索引的行控制器扳碍。假如你成功設(shè)置了 controller 的 flight 屬性,會(huì)觸發(fā) didSet 監(jiān)視器并且設(shè)置 table row 中所有的標(biāo)簽。

是時(shí)候看看勞動(dòng)成果了仙蛉。編譯運(yùn)行笋敞。你會(huì)看到 table row 已經(jīng)被相關(guān)的航班信息填充了:

響應(yīng)行的選中事件

首先去重寫 WKInterfaceController 中主要負(fù)責(zé)處理 table row 選中事件方法定義。

往 ScheduleInterfaceController 中添加如下代碼:

override func table(table: WKInterfaceTable, didSelectRowAtIndex rowIndex: Int) {letflight = flights[rowIndex]? presentControllerWithName("Flight", context: flight)}

這里使用行的索引來檢索出合適的航班信息荠瘪。之后顯示航班詳情界面,作為 context 屬性傳遞 flight 給這個(gè)界面夯巷。presentControllerWithName(_:context:) 方法的name參數(shù)是你在 storyboard 中設(shè)置identifier的值。

現(xiàn)在你需要更新 FlightInterfaceController 來使用 context 的值來設(shè)置它的界面哀墓。

打開 FlightInterfaceController.swift,找到 awakeWithContext(_:) 趁餐。替換這句代碼:

flight = Flight.allFlights().first!

為如下代碼:

ifletflight = contextas? Flight { self.flight = flight }

這里嘗試轉(zhuǎn)換 context 為 Flight 對(duì)象。如果轉(zhuǎn)換成功就可以使用它來設(shè)置self.flight,這會(huì)觸發(fā)屬性監(jiān)視器來設(shè)置界面篮绰。

最后,編譯運(yùn)行后雷。如果你點(diǎn)擊某個(gè) table row ,你會(huì)看到航班詳情界面模態(tài)彈出,顯示你選中的航班的詳情:

恭喜!你已經(jīng)完成你的第一個(gè)列表并且使用真實(shí)數(shù)據(jù)填充它;太棒了!

總結(jié)

這里目前教程的完整實(shí)例項(xiàng)目

在這片教程中你學(xué)習(xí)到如何往界面控制器中添加一個(gè)列表,設(shè)計(jì) table row 界面,創(chuàng)建一個(gè)行控制器,處理 table row 選中,顯示其他界面控制器,傳遞 contexts。在這20分鐘里面做了很多事情!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末臀突,一起剝皮案震驚了整個(gè)濱河市勉抓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌候学,老刑警劉巖琳状,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盒齿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)困食,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門边翁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人硕盹,你說我怎么就攤上這事符匾。” “怎么了瘩例?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵啊胶,是天一觀的道長。 經(jīng)常有香客問我垛贤,道長焰坪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任聘惦,我火速辦了婚禮某饰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘善绎。我一直安慰自己黔漂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布禀酱。 她就那樣靜靜地躺著炬守,像睡著了一般。 火紅的嫁衣襯著肌膚如雪剂跟。 梳的紋絲不亂的頭發(fā)上减途,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音浩聋,去河邊找鬼观蜗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛衣洁,可吹牛的內(nèi)容都是我干的墓捻。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼砖第!你這毒婦竟也來了撤卢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤梧兼,失蹤者是張志新(化名)和其女友劉穎放吩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羽杰,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渡紫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了考赛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惕澎。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖颜骤,靈堂內(nèi)的尸體忽然破棺而出唧喉,到底是詐尸還是另有隱情,我是刑警寧澤忍抽,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布八孝,位于F島的核電站,受9級(jí)特大地震影響鸠项,放射性物質(zhì)發(fā)生泄漏干跛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一祟绊、第九天 我趴在偏房一處隱蔽的房頂上張望驯鳖。 院中可真熱鬧,春花似錦久免、人聲如沸浅辙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽记舆。三九已至,卻和暖如春呼巴,著一層夾襖步出監(jiān)牢的瞬間泽腮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工衣赶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诊赊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓府瞄,卻偏偏與公主長得像碧磅,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鲸郊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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