Swift - TableViewCell deletion programmatically
前言:
至於要在MyCell執行deleteCell()要怎麼做?很簡單,只要在MyCell給定一個MyTableViewController的變數,先將其設為Optional:
修改MyCell裡的handleAction():
將print("tapped")刪除,並加入
用來刪除自己(參數帶入self)
這樣就完成了嗎?不!
你可以在myTableViewController?.deleteCell(cell: self)設下breakpoint,並執行。
接著在模擬器或實機按下cell旁的delete按鈕,可以在debug area看到myTableViewController的值為nil:
Why? 因為我們在
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
這個函式內,沒有賦值給myCell裡的myTableViewController變數,所以修改tableView(_:, cellForRowAt:)這個函式裡的內容:
接著要驗證按下Delete按鈕後,控制流程是否正確,我們先移除剛剛handleAction()的breakpoint,接著在deleteCell()處設下中斷點,並執行。
然後按下模擬器或實機上cell的Delete按鈕,如果會出現下圖這樣正常觸發,恭喜你,目前為止大致做對了!
下一步是要呼叫刪除特定列的函式。我們在deleteCell()函式內呼叫這樣的一個函式:
至於參數的傳入,根據Apple Developer Documentation對此一函式的說明文件:
好的,現在就要來給定刪除的索引列,至於要取得當前刪除的列,我們可以用indexPathForCell()這個函式取得當前列,故將整個deleteCell()函式修改如下:
接著執行看看。
.
.
咦?怎麼crash了
不對呀,我刪除的函式有被呼叫到,也沒有丟錯參數,怎麼會錯呢?
哦! 我想到了
我刪除某一列的時候,那整個TableView的Cell內容是不是就也要跟著刪除?
是的,當我們執行上面的deleteRows()之後,事實上只剩下2個cell可以顯示內容,而我們最初的items共有3個項目(也就是第13行建立的items陣列),3個項目怎麼可以塞進2個cell呢?當然不行啊,況且我的目的是要連同cell的內容一併刪除,所以要在deleteRows()執行之前,先找出items陣列欲刪除的某一筆資料,換句話說就是要刪除某一cell所對應的items陣列索引內的某一筆資料,故我們要再次修改deleteCell()函式內容如下:
再執行一次,是不是可以順利刪除資料了呢?
可以的話,恭喜你學到一課 Woh~ nice !
大學畢業了,在前往研究所之路的過渡期,雖然心裡想著這是我最後一個暑假,應該要好好玩、大力玩,但是心裡總有一點聲音在警惕自己不要虛度這年輕寶貴的時刻,所以老樣子,承襲每年放寒暑假的傳統,self-learning iOS is still my main task to do !
其實以往都有在持續(或是說斷斷續續)跟Swift培養感情,但是礙於自己蠻懶的,一方面學的比較沒那麼積極、一方面部落格也就沒什麼在寫,所以趁現在剛學到一個新概念,趕緊花時間記錄下來,至於今天的主題也寫在標題上了,要來紀錄如何用手刻(programmatically)讓UITableViewCell從UITableView進行刪除的動作。
這也是我第一次用刻UI的方式做整個小專案的練習,以前Storyboard用久了,順便利用這個暑假學習純code來開發一個app。
而今天的教學資源來自Let's build that app這個頻道的這個影片中的一部份實作內容,我follow這個頻道也算蠻久了,無聊就會找這個講師的影片配飯看、照三餐看(誤),我只能說這個講師非常厲害,好啦,廢話不多說,我們趕快開始吧!
正文:
首先,請到我的Github下載原始專案:
打開之後,修改一下Identity,並執行:
可以看到已經有3列的cell,且每個cell除了有顯示label name (item 1, item 2, item 3),還各自有一個delete按鈕,我們要做的就是在按下delete之後,會將對應列的cell刪除。
沒有問題後,我們要建立一個刪除UITableViewCell的動作,所以我們寫一個函式在MyTableViewController的class內:
至於要在MyCell執行deleteCell()要怎麼做?很簡單,只要在MyCell給定一個MyTableViewController的變數,先將其設為Optional:
修改MyCell裡的handleAction():
將print("tapped")刪除,並加入
用來刪除自己(參數帶入self)
這樣就完成了嗎?不!
你可以在myTableViewController?.deleteCell(cell: self)設下breakpoint,並執行。
接著在模擬器或實機按下cell旁的delete按鈕,可以在debug area看到myTableViewController的值為nil:
Why? 因為我們在
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyCell
myCell.nameLabel.text = items[indexPath.row]
return myCell
}這個函式內,沒有賦值給myCell裡的myTableViewController變數,所以修改tableView(_:, cellForRowAt:)這個函式裡的內容:
接著要驗證按下Delete按鈕後,控制流程是否正確,我們先移除剛剛handleAction()的breakpoint,接著在deleteCell()處設下中斷點,並執行。
然後按下模擬器或實機上cell的Delete按鈕,如果會出現下圖這樣正常觸發,恭喜你,目前為止大致做對了!
下一步是要呼叫刪除特定列的函式。我們在deleteCell()函式內呼叫這樣的一個函式:
至於參數的傳入,根據Apple Developer Documentation對此一函式的說明文件:
好的,現在就要來給定刪除的索引列,至於要取得當前刪除的列,我們可以用indexPathForCell()這個函式取得當前列,故將整個deleteCell()函式修改如下:
接著執行看看。
.
.
咦?怎麼crash了
不對呀,我刪除的函式有被呼叫到,也沒有丟錯參數,怎麼會錯呢?
哦! 我想到了
我刪除某一列的時候,那整個TableView的Cell內容是不是就也要跟著刪除?
是的,當我們執行上面的deleteRows()之後,事實上只剩下2個cell可以顯示內容,而我們最初的items共有3個項目(也就是第13行建立的items陣列),3個項目怎麼可以塞進2個cell呢?當然不行啊,況且我的目的是要連同cell的內容一併刪除,所以要在deleteRows()執行之前,先找出items陣列欲刪除的某一筆資料,換句話說就是要刪除某一cell所對應的items陣列索引內的某一筆資料,故我們要再次修改deleteCell()函式內容如下:
再執行一次,是不是可以順利刪除資料了呢?
可以的話,恭喜你學到一課 Woh~ nice !
留言
張貼留言