說明:
本系列教程改編自raywenderlich.com中的iOS Apprentice系列,有需要的童鞋請移步到這裡購買英文版原教程:https://store.raywenderlich.com/products/ios-apprentice
歡迎繼續我們的學習。
在上一課的內容中,我們成功的在界面中添加了一個表視圖,然後讓它顯示了幾行數據信息。不過看起來是完全相同的,都是佔位文字」Label「。
接下來讓我們稍微做點調整,起碼讓每一行顯示的內容都不同吧。
將行數據添加到cell中
在Xcode中打開storyboard?文件,然後選擇table view cell中的標籤label。如果你怕選擇錯了,可以在左側的視圖元素列表中點擊選擇。
然後在Xcode右側的?面板中切換到Attributes Inspector,將Tag這一欄的數值設定為1000.
設置這樣?個tag(標記)究竟有神?用處呢?通過tag標記我們可以給?用戶界?中的視覺元素設置一個 數字標識符,這樣在後續需要使用到它的時候可以很容易找到。那麼這?為神?要設置為1000呢? 其實沒神?特別道理,只要這個數字不是0就行(因為0是標記的默認數值)。如果你願意,?你最習慣的1024也可以,你懂的~
注意:
?定要確定你的標記值是設置在標籤上。初學者最常犯的錯誤就是給table view cell設置了標記值,?不是給Label標籤設置。這樣最後的結果就不是你所期待的了。
接下來在Xcode中打開ChecklistViewController.swift,更改tableView(_:cellForRowAt:)
方法的代碼如下:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ChecklistItem", for: indexPath) //添加下面的代碼 let label = cell.viewWithTag(1000) as! UILabel
if indexPath.row == 0 { label.text = "流浪地球" } else if indexPath.row == 1{ label.text = "瘋狂的外星人" } else if indexPath.row == 2{ label.text = "飛馳人生" } else if indexPath.row == 3{ label.text = "喜劇之王" }else if indexPath.row == 4{ label.text = "小豬佩奇過大年" } //結束以上的新代碼段 return cell }
在這個?法體中,第?行代碼我們之前已經了解過了,它的作?就是獲取prototype cell的拷貝(不 管是新的還是回收利用的),然後把它賦予新創建的一個cell本地變數,其類型是
UITableViewCell。 接下來的就是新東西了,?先是這??:
let label = cell.viewWithTag(1000) as! UILabel
這?我們請求獲取cell中的標記為1000的?視圖,這個標記就是我們剛才在storyboard中在標籤上所設置的。通過這種方法,我們就獲取了?個到該UILabel標籤對象的引?。 實際上,通過使?tag標記的?式來獲取到某個視覺元素的引?用是?常方便的,可以省掉了聲明 @IBOutlet變數的步驟。
思考:
好吧,為神?這?我們不在視圖控制器中添加?個IBOutlet屬性聲明,然後把cell的標籤和 storyboard中的outlet關聯在?起呢?
在table視圖中可能不??個cell,?而個cell都會擁有?己的標籤。如果我們使用之前的?法,將prototype cell中的標籤和視圖控制器中的某個outlet關聯在?起,那麼該屬性只能指向其中?個cell的標籤,?不是所有。
需要注意的是,label標籤屬於cell的?視圖,?不是屬於視圖控制器,因此我們不能為它創建?個outlet。聽到這句話是不是有點糊塗?Don』t panic!不要恐慌~
在後續的教程中我們將繼續回到這個話題,但在這?就暫時別管了。
到底什麼是indexPath呢?
在上一課的內容中,我們教過大家一個小小的技巧。當你在Xcode的源代碼中看到某個方法、參數或屬性之前從來沒見過時,可以按下option鍵,然後點擊關鍵詞查看。
這個大概解釋下indexPath的作用。
簡單來說,它是指向表中某個特定行的對象。當表視圖為cell請求數據源的時候,程序會查看indexPath.row的?編號屬性,從 ?確定該cell需要哪?行數據。
在使?表視圖的時候,我們還有可能把不同的?放進section?面。?如在地址薄應用中,我們會使?姓來查找聯繫?人。所有姓以A開頭的聯繫?人會被分到同?個section組中,?所有姓以B開頭的聯繫人會被放到另?個section組中,以此類推。 為了查找某?行所屬的section,我們需要使?indexPath.section屬性。因為Checklists應?用不會?到這種分組方式,所以可以暫時忽略NSIndexPath的section屬性。
繼續回到代碼。
接下來的?行代碼應該不會讓你很頭大。
if indexPath.row == 0 { label.text = 「觀看《流浪地球》」 } else if indexPath.row == 1{ label.text = 「觀看《瘋狂的外星人》」 } else if indexPath.row == 2{ label.text = 「觀看《飛馳人生》」 } else if indexPath.row == 3{ label.text = 「觀看《喜劇之王》」 }else if indexPath.row == 4{ label.text = 「觀看《小豬佩奇過大年》」 }
之前我們已經學過if- else if -else的語法結構。這?程序檢查了indexPath.row的屬性值,其中包含了行編號,然後根據不同的?編號賦予標籤中的?本不同的值。
在這裡,我們列出了2019年春節賀歲檔要看的幾部熱門電影,作為重要的待辦事項~
作為一個鐵杆的科幻迷,當然是首推《流浪地球》了。
當然,要吐槽一下的是,《三體》究竟什麼時候可以拍出來呢?
需要特別注意的是,第?行的index屬性值是0,?不是1。
在程序世界裡,萬物從0開始。所有如果你的列表中有四個事項,那麼它們的編號是0,1,2和3。當然 這個有點反?人類,畢竟我們習慣了數??的?指1,2,3,4。不過在程序世界?面就是這樣的。因 此,對於第?個section中的第?行,indexPath.row的值是0,?indexPath.section的值也是0.第?行的編號是1,第三行的編號是2,以此類推。
其實萬物從0開始也是符合陰陽太極理論的。?子?過:「道?一,?生?,?生三,三?萬物。」 這?的道可以看做0。
萬物負陰?抱陽,沖?以為和。0和1構成了變幻?窮的程序世界,豈不對應了陰陽?
當然,以上只是瞎掰,不要當真。
好了,現在可以運?應用,看看我們有哪些事情要做的~
可以看到,現在我們的時間管理軟體顯示了5件事情,也就是我們要看的5部賀歲片~
現在讓我們回顧一下如何使用tableView(_:cellForRowAt:) 為表視圖提供數據。
首先,我們需要獲取一個UITableViewCell對象。
然後,根據indexPath的行編號來更改cell中的內容。
小練習:
如果你閑得無聊,打算把這5部賀歲片反反覆復看個幾十遍。那麼,現在可以嘗試著往表視圖中填充100行數據。
1.把tableView(_:numberOfRowsInSection:) 方法的返回值設置為100.
2.更改剛才所添加的設置label.text的相關代碼如下:
if indexPath.row % 5 == 0 { label.text = "觀看《流浪地球》" } else if indexPath.row % 5 == 1{ label.text = "觀看《瘋狂的外星人》" } else if indexPath.row % 5 == 2{ label.text = "觀看《飛馳人生》" } else if indexPath.row % 5 == 3{ label.text = "觀看《喜劇之王》" }else if indexPath.row % 5 == 4{ label.text = "觀看《小豬佩奇過大年》" }
這?用到了模操作符 %,如果你的中?學數學還沒忘光光的話,可能對它還有?分印象。模操作其實就是返回除法計算的餘數。?如13 %4 =1,因為13除以4的結果是3.25,?整數來表示的話除法的結果是3,然後餘數是1.?12%4=0,因為沒有餘數。
這樣?來,第1?,第6?,第11?,第16?,等等都會顯示」觀看《流浪地球》」,第 2?行,第7?,第12?,等等都會顯?"觀看《瘋狂的外星人》」,以此類推。
第?行: 0%5 = 0
第七?: 6%5 =1(和第??相同)
第九行: 8%5 = 3(和第四?相同)
。。。。。。 後?就不再折騰了,相信你百分百可以看懂了。
假如你還是看不懂,也沒關係,只要知道這?我們?了?個?小的技巧快速填滿了整個表。 運?應?,可以看到類似下?的界?:
小技巧:
如果你是在模擬器上進行測試,那麼可以按下滑鼠左鍵,然後上下拖動,就跟在真機上使用手指拖動一樣~但是如果不按下滑鼠左鍵,是沒辦法拖動的。
思考:
答案:
100個?
錯!
顯而易見,100行數據,難道不是用100個cell嗎?
遺憾的是人類的直覺往往有誤導性,雖然我們有100?數據,但在屏幕上最多同時可以容納14個cell。
等等,哥剛才仔細數了數,不是只有13個cell嗎?沒錯,如果表中的內容靜?,的確我們只看到13 個cell,但如果你上下滾動表視圖,會發現有時上?的cell還在顯?,?新的cell已經在底部出現了。 因此?少需要14個cell。
如果你滾動表視圖的速度?夠快,或許可能表視圖需要更多的臨時cell,這?點我不確定。不過這?點重要嗎?不重要嗎?是的,不重要。你只需要表視圖會替你完成這個任務就?了。我們要做的事情是,當表視圖需要?個cell的時候向它提供,同時?相應行的數據信息來填滿這個cell就好了。
總之,通常來說所需要的cell比row要少。因為如果我們的應用為每一行數據都提供一個cell,iOS很快就會榨乾了iPhone或iPad的內存,哪怕你是最新最NB的可以秒殺MBP的iPad Pro也不行。哪怕你有成千上萬條數據,我們在屏幕上需要查看的永遠也就那麼幾條十幾條而已,否則整個程序立馬就崩了~
現在可能你已經明白了為什麼UITableView表視圖把row和cell分的這麼請,row代表著數據,可能有成千上萬條甚至更多。而cell則是屏幕上可視化的部分,最多也就那麼十來條而已。
奇怪的崩潰
很多童鞋在通過郵件、私信或者論壇提問的時候,都會提到同樣的一個問題:」為什麼我照著你的內容一步步操作,但是程序還是崩潰了?到底哪裡出了問題?「
在開發的過程中,有無數種原因可能導致程序崩潰。
而其中一種就是你可能無意中在代碼中設置了一個breakpoint(斷點)。
斷點其實是個好東西,它可以幫助我們對代碼進行調試。使用斷點的方式是在源代碼的某一行或某幾行添加斷點,然後跳轉到Xcode的調試器。當斷點發揮作用的時候,給你的感覺跟程序崩潰是一樣的,但實際上程序只是暫停而已。
下面我們看一看斷點到底是長什麼樣的。
如果你的應用突然崩潰了,然後源代碼的某一行上面出現了藍色的箭頭,那麼Don』t panic,你只是」觸發「了一個斷點而已。
有些時候我們會為了調試的需要而設置斷點,但還有些時候是因為不小心誤操作而已,我也曾經犯過類似的錯誤~
移除斷點其實很簡單,只要按下滑鼠左鍵,把它向左拖出Xcode窗口就好了。
當然,還有一種方式就是點擊這個斷點,那麼它會從藍色變成灰色。斷點仍然存在,只不過會暫停發揮作用。
好了,一下子學了這麼多,我們也該休息一下了。
我們下一課再見~
聯繫方式:
個人微信: iseedo
微信公眾號:icodefun
答疑說明:
大家後續有開發相關的問題請到課程答疑專區提問http://icode.fun/ask/forum.php
接下來當然是福利時刻了~
TAG:iOS開發 | iPhone | 蘋果公司(AppleInc.) |