iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 20
0

前言

昨天介紹了 protocol 傳值得方法,今天利用一個 save 的 button 可以整理訂單的陣列,順便藉由 segue 將頁面轉移到購物車頁面,除了轉移頁面外,還可以順便把訂單的陣列資料傳過去。

1. 設定購物車的 Table View 設定

table view怎麼設定就不再講了...一個 table view cell 裡面放兩個 Label 元件

新增檔案繼承 UIViewController
命名為 ShoppingCartViewController.swift

import UIKit

class ShoppingCartViewController: UIViewController, UITableViewDelegate, UITableViewDataSource

{
    
    var shoppingCartName: [String] = []
    var shoppingCartCount: [Int] = []
    
    @IBOutlet weak var shoppingTableView: UITableView!


    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return shoppingCartName.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "shoppingCartCell", for: indexPath) as! ShoppingCartTableViewCell
        cell.shoppingNameLabel.text = shoppingCartName[indexPath.row]
        cell.shoppingCountLabel.text = "\(shoppingCartCount[indexPath.row])"

        return cell
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}

新增檔案繼承 UITableViewCell
命名為 ShoppingCartTableViewCell.swift

import UIKit

class ShoppingCartTableViewCell: UITableViewCell {

    @IBOutlet weak var shoppingNameLabel: UILabel!
    @IBOutlet weak var shoppingCountLabel: UILabel!
    
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

2. 將 save button 連結到 ShoppingCartViewController

如下圖所示,直接從 save button 右鍵拖曳藍線拉到 ShoppingCartViewController,就會出現 segue 箭頭,點選箭頭在右側 Attributes 頁面中設定 segue identifier 為 segue

3. 回到 drinkViewController.swift 覆寫 prepare(for segue: UIStoryboardSegue sender: Any?) 方法

這邊值得一提的是,為了讓資料更好分辨,我將一開始的儲存資料型態由陣列改為字典 ["key": value] = ["飲料名稱": 訂購數]

var teaList = ["茉莉綠茶": 0, "阿薩姆紅茶": 0, "四季春茶": 0, "黃金烏龍": 0, "微檸檬 紅/青": 0, "檸檬 綠/青": 0, "梅果綠": 0, "8冰綠": 0, "養樂多綠": 0, "蜂蜜綠": 0, "芒果青": 0, "冰淇淋紅茶": 0, "鮮柚綠": 0, "波霸 紅/綠/青/烏": 0, "波霸奶茶(大顆)": 0, "波霸奶綠(大顆)": 0, "珍珠 紅/綠/青/烏": 0, "珍珠奶茶(小顆)": 0, "珍珠奶綠(小顆)": 0, "椰果奶茶": 0, "仙草奶凍": 0, "鮮柚汁(季節限定)": 0]

也因此可以利用訂購數量是否大於0來判別哪些飲料被訂購了

teaList.forEach { teaList in
                if teaList.value > 0 {
                    selecTeaName.append(teaList.key)
                    selecTeaCount.append(teaList.value)
                }

一開始以為這樣就完成了,結果自己測試的時候發現,每次按 save button ,selecTeaName 和 selecTeaCount 陣列內容就一直增加,所以只好多加一個判斷 selecTeaName是否存在

teaList.forEach { teaList in
                if teaList.value > 0 {
                    if selecTeaName.index(of: teaList.key) = nil {
                        selecTeaName.append(teaList.key)
                        selecTeaCount.append(teaList.value)
                    } else {
                        selecTeaCount[selecTeaName.index(of: teaList.key)] = teaList.count
                    }
        

最後測試的時候,又發現如果使用者 save 過一次,接著右將訂購數歸0再次按下 save,訂購飲料不會刪除

只好再加入一個判斷來刪除數字歸0的飲料,而上面所講的判斷式也用 if let 的方法來判斷是否 nil,來簡化程式碼

teaList.forEach { teaList in
                if teaList.value > 0 {
                    if let i = selecTeaName.index(of: teaList.key) {
                        selecTeaCount[i] = teaList.value
                    } else {
                        selecTeaName.append(teaList.key)
                        selecTeaCount.append(teaList.value)
                    }
                } else {
                    if let i = selecTeaName.index(of: teaList.key) {
                        selecTeaName.remove(at: i)
                        selecTeaCount.remove(at: i)
                    }
                }
            }

以上就是將訂單儲存下來的判斷式,接著要把資料傳給購物車頁面

if segue.identifier == "segue" {
    let VC = segue.destination as! ShoppingCartViewController
    
    // 判斷式... 略
    
    VC.shoppingCartName = selecTeaName
    VC.shoppingCartCount = selecTeaCount
}

4. 完成,效果如下

後記

耶!!訂購單顯示了,但是我的 tab bar也不見了...
看來我又有新的問題要解了...哭!


上一篇
Day19 - bug解除 (自定義 delegate 傳值:protocol應用)
下一篇
Day21 - 消失的 Tab Bar
系列文
無中生有-從SWIFT語法學習到iOS APP的開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
nick55002
iT邦新手 5 級 ‧ 2021-07-04 23:00:16

想詢問selecTeaName和selecTeaCount,是要在哪裡設定呢?

看更多先前的回應...收起先前的回應...
soj iT邦新手 4 級 ‧ 2021-07-05 09:00:29 檢舉

這個專案我已經沒有維護了,之前保留的檔案也有殘缺...
或許可以參考我上一篇文章的內容,它是從 drinkViewController 裡面 tableView 中傳值過來的一個陣列

nick55002 iT邦新手 5 級 ‧ 2021-07-05 13:12:33 檢舉

謝謝你的回覆,好的我試看看
因為我也是想練習看看做類似的功能
但一直卡住,不知道可不可以參考你的檔案(有殘缺沒關係)
如果可以寄給我嗎? (nick55002@gmail.com
謝謝~~

nick55002 iT邦新手 5 級 ‧ 2021-07-06 18:02:42 檢舉

將teaList改為字典後,以下這行就會出現錯誤訊息

cell.teaNameLabel?.text = teaList[indexPath.row]

錯誤訊息:No 'subscript' candidates produce the expected contextual result type 'String?'

soj iT邦新手 4 級 ‧ 2021-07-09 08:03:46 檢舉

我得提醒一下,我這個專案很舊了,語法差異很多喔,我放在我的 github 上了
https://github.com/SoJ0825/wanttodrink

teaList 是 [String: Int]。你給的 Key: indexPath.row 是 Int,會無法解析字典

nick55002 iT邦新手 5 級 ‧ 2021-07-13 22:06:59 檢舉

好的,感謝你的提供與解說
只是可惜的是,不是Day19和Day20 利用stepper方式的code了~

我要留言

立即登入留言