#37 在 TableView Cell 裡使用 button 顯示下一頁,並傳資料到下一頁

練習動態 TableView + UIButton + 利用轉換座標的 convert function 判斷點選的 button 在哪個 cell

--

最近在練習訂飲料 App 的時候,想做類似像大苑子的訂購系統,可以從飲料列表按+button之後進入到下一頁,並傳資料到下一頁的功能。

這個功能如果TableView 是利用Static cells 來做的話,就比較簡單。但是如果是Dynamic Prototypes 來做的話,就必須讓 App 知道我現在按的 button 是在那個 Cell,這樣才能傳正確的資料到下一頁。

我們就來一步一步學習如何實現這個功能。

事先準備

  1. 首先,建立一個新的專案,命名為 UIbutton at TableView Cell

2. 因為等一下我們直接在 TableView Controller直接建立程式,所以我們切換到 Main StoryBoard,將 ViewController 跟 ViewController.swift 刪除

ViewController.swift 刪除時選取 Move to Trash就可以了

刪除完如下圖

3. 在 Main StoryBoard 加入 TableView Controller

然後在is initial View Controller 打勾,讓 App 打開一進來就直接讀取這個 App。

4. 建立一個新的TableViewController.swift 檔案,等一下將這個檔案聯結到在 Main StoryBoard 的 TableView Controller 的 Class ,這樣我們就可以讓TableView Controller 做我們想讓他做的事情。

按 command + N,選 Cocoa Touch Class 然後按 Next

將 Subclass of 選擇 UITableViewController,Class 命名為MenuTableViewController,然後按 Next

再來就是 Targets 打勾,然後按Create

這樣,MenuTableViewController.swift就建立完成了

5. 再來就是將 TableViewController 的 Class 指定為 MenuTableViewController.swift

點選 Main StoryBoard,點選 Table View Controller,點選show the identity inspector,將 Class 指定為MenuTableViewController,這樣子,我們就可以對 TableView Controller 為所欲為了。

6. 再來,我們來自定義 TableView Cell 裡的內容。

先按+(Library)選擇 Label, 將 label 拉到 Cell 的左邊。

將 Label 的 width 調到 200

同樣的方法將 button 加到 Cell 的右邊

7. 我們也要將 Cell 新增一個 TableViewCell.swift 檔案,將 cell 的 Class 指定至新的 TableViewCell.swift

一樣按 command + N,選 Cocoa Touch Class,將 Subclass of 選擇 UITableViewCell,Class 命名為MenuTableViewCell

然後將 Cell 的 Class 指定為 MenuTableViewCell

8. 要將 Cell 的內容顯示出來,必須將 cell 註明一個ID,這樣等一下程式才知道是要使用哪一個 Cell

就把 剛剛自定義的Cell 的ID 取名為MenuTableViewCell吧~

9. 最後的準備工作就是將目前自定義 cell 裡的 button 跟 Label 拉 IBOutlet

按住 Control + Option + command 然後按 enter 將Assiatant 視窗叫出來

然後點選 MenutableViewCell 底下的 Content View 然後選擇 MenuTableViewCell.swift

將 Label 拉 IBOutlet 並命名為 drinkLabel,將 button 拉 IBOutlet 並命名為 addButton

10. 最後, 將 Button 的 title 刪除,然後 Image 選擇 Plus,這樣 UIButton 就會顯示+的符號

以上,事前工作準備完成。

開始寫程式讓飲料名稱顯示在 tableview cell 上

點選 MenuTableViewController.swift,我們會用到的 TableView data source 的 function只有

  • func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

所以其他沒有必要的程式碼就可以刪除了。結果如下圖

再來我們建立飲料菜單的 Array,menus[]

然後在tableView 的 numberOfRowsInSection function 顯示 menus 的 cell 數量

再來,在tableView 的 cellForRowAt function 顯示 cell 內容

有幾個關鍵點要輸入

  1. withIdentifier 的字串要輸入我們剛剛自定義的Cell 的ID 也就是MenuTableViewCell
  2. cell 要轉型成我們自己建立的MenuTableViewCell,這樣才可以讀取到 MenuTableViewCell裡的東西

這樣就會變成

在tableView 的 cellForRowAt function 裡有一個參數 為 indexpath,這個參數就是讓cell的每一行可以依照 menus 裡有多少種飲料來決定顯示的內容。

所以我們就可以定義menu

意思就是cell 的第一行 就是 indexpath.row = 0

這樣 menus[0] 就是”春熙柳橙翡翠”

然後 cell 的 drinkLabel 的文字就是 menu

完整程式碼如下

這樣子按下模擬器畫面就會顯示如下:

傳資料到下一頁

傳資料到下一頁有很多方法,這個範例將使用 IBSegueAction的方法。

首先,先切換到 Main StoryBoard,按+(Library)選取 View Controller,然後拉到 StoryBoard 空白處

結果如下

再來在新的 View Controller 上加一個 Label,讓 Menu TableView Controller 的飲料名稱可以讀取,然後顯示在 Label上。

一樣,按+選 Label 拉到 View Controller。

將 Label 的尺寸設為width 300,hight 50,字體 30, 置中

然後為新的 View Controller 建立新的 Class File,

一樣按 command + N,選 Cocoa Touch Class,將 Subclass of 選擇 UIViewController,Class 命名為DrinkLabelViewController

然後將新的 View Controller 的 class 指定為DrinkLabelViewController

將 Label 拉 IBOutlet ,命名為drinkNameLabel

在DrinkLabelViewController定義從上一頁要傳過來的資料為飲料名稱的字串, 並定義初始值

ViewDidLoad Function 裡要指定 drinkNameLabel 顯示的字串就是 drinkName

這樣,DrinkLabelViewController 的程式碼就完成了

建立 @IBSegueAction 並輸入程式碼

回到MenuTableViewController

將+ uibutton 拉 Sequew 到 DrinkLabelViewController, 選 Show

就會出現 Seque 了

從 seque 按滑鼠右鍵建立@IBSegueAction

命名為showDrinkName, arguments 選 sender

@IBSegueAction func showDrinkName(_ coder: NSCoder) -> DrinkLabelViewController? 輸入

程式碼說明如下:

因為我們是利用 UIbutton 建立 seque,按 button 之後就可以顯示及傳送資料到下一頁,所以我們將 sender 轉型為 UIButton。

button?.convert 這個 funtion是讓app 知道按鈕的位置,從 tableView 的 坐標(0,0)到按鈕的位置,這樣就可以知道是第幾個 cell 的按鈕。

tableView.indexPathForRow(at: point) 回傳的是 cell 的indexpath 的值,包含了 cell 的 section 跟 row 值。

因為 point 跟 indexPath是 optional 的值,所以用 if let ,如果有值的話,就執行以下程式碼,如果沒有的話就回傳 nil。

當有 indexpath 值的時候,就可以利用 indexpath.row 值來知道是第幾行,那 menus[indexpath.row] 就是那一行的飲料名稱。

這樣就可以將 cell 裡的資料,使用 UIButton 將資料傳到下一頁了。

最終結果如下

--

--