#25–5 期末< 5>好味小姐罐頭訂購APP-Notification資料傳到下一頁
最近都在忙其他事就沒有持續更新☕☕
上次提到使用IBSegueAction傳資料到MenuDetailTableViewCell裡,
這次要做的是把選擇的資料傳到其他的ViewController(如果以這次的專案來看就是要傳到OrderViewController)。如下圖紅色箭頭:
如果要看藍色箭頭資料要怎麼傳送可以看上一篇期末< 4>的文章~
關於Notification
我們可以分成以下4個步驟:
- 發送通知:
➡使用 NotificationCenter.default.post 發送通知,將相關數據打包在 userInfo 字典中並附加到通知中。
NotificationCenter.default.post(name: Notification.Name("OrderAdded"), object: nil, userInfo: userInfo)
2. 添加通知觀察者:
➡在 viewWillAppear 方法中,使用 NotificationCenter.default.addObserver 註冊觀察者,指定接收通知的名稱和處理函數。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(handleOrderAddedNotification(_:)), name: Notification.Name("OrderAdded"), object: nil)
}
3. 處理通知:
➡實現一個方法(如 handleOrderAddedNotification),該方法在接收到通知時被調用,並處理通知的數據。
// 記得要加@objc
@objc func handleOrderAddedNotification(_ notification: Notification) {
// 處理通知的數據
}
4. 移除通知觀察者:
➡在 viewWillDisappear 方法中,使用NotificationCenter.default.removeObserver 移除觀察者,避免不必要的通知接收。
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: Notification.Name("OrderAdded"), object: nil)
}
➡在 deinit 方法中,也移除觀察者,確保在對象釋放時不再接收通知,防止洩漏問題產生。
deinit {
NotificationCenter.default.removeObserver(self)
}
所以notification的順序:
發送通知→ 添加通知觀察者→處理通知→移除通知觀察者
專案開始:
先附上完成的gif~
YouTube shorts link:
Code:
發送通知:
建立userInfo字典並使用NotificationCenter.default.post…..
@IBAction func addOrderButtonTapped(_ sender: UIButton) {
let orderQty = orderQty.text ?? ""
let name = nameLabel.text ?? ""
let title = titleLabel.text ?? ""
let price = priceLabel.text ?? ""
let detailPrice = pricedetailLabel.text ?? ""
let titleImageUrlString = productInfo.titleImage?.absoluteString ?? ""
let imageUrlString = productInfo.image?.absoluteString ?? ""
let titleImageUrl = URL(string: titleImageUrlString)
let imageUrl = URL(string: imageUrlString)
let newDetailOrder = DetailOrderData(name: name, detailPrice: detailPrice, price: price, orderQty: orderQty, imageUrl: imageUrl)
// 檢查是否存在相同 title 的 TitleOrderData
if let index = SharedData.shared.titleOrders.firstIndex(where: { $0.title == title }) {
// 如果存在,添加新的 DetailOrderData
SharedData.shared.titleOrders[index].detailOrderData.append(newDetailOrder)
} else {
// 如果不存在,創建新的 TitleOrderData 並添加到 titleOrders
let newTitleOrder = TitleOrderData(title: title, titleImageUrl: titleImageUrl,detailOrderData: [newDetailOrder])
SharedData.shared.titleOrders.append(newTitleOrder)
}
let userInfo: [String: Any] = [
"orderQty": orderQty,
"name": name,
"title": title,
"price": price,
"detailPrice": detailPrice,
"titleImageUrl": titleImageUrlString,
"imageUrl": imageUrlString
]
NotificationCenter.default.post(name: Notification.Name("OrderAdded"), object: nil, userInfo: userInfo)
print("成功使用 userInfo 發送通知,内容:\(userInfo)")
dismiss(animated: true)
}
添加通知觀察者:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(handleOrderAddedNotification(_:)), name: Notification.Name("OrderAdded"), object: nil)
}
處理通知:
@objc private func handleOrderAddedNotification(_ notification: Notification) {
if let userInfo = notification.userInfo {
let title = userInfo["title"] as? String
let orderQty = userInfo["orderQty"] as? String
let name = userInfo["name"] as? String
let price = userInfo["price"] as? String
let detailPrice = userInfo["detailPrice"] as? String
let titleImageUrlString = userInfo["titleImageUrl"] as? String
let imageUrlString = userInfo["imageUrl"] as? String
let titleImageUrl = titleImageUrlString != nil ? URL(string: titleImageUrlString!) : nil
let imageUrl = imageUrlString != nil ? URL(string: imageUrlString!) : nil
let newDetailOrder = DetailOrderData(name: name, detailPrice: detailPrice, price: price, orderQty: orderQty, imageUrl: imageUrl)
if let title = title, let index = SharedData.shared.titleOrders.firstIndex(where: { $0.title == title }) {
SharedData.shared.titleOrders[index].detailOrderData.append(newDetailOrder)
} else {
if let title = title {
let newTitleOrder = TitleOrderData(title: title, titleImageUrl: titleImageUrl, detailOrderData: [newDetailOrder])
SharedData.shared.titleOrders.append(newTitleOrder)
}
}
DispatchQueue.main.async {
self.mainTableView.reloadData()
}
}
}
移除通知觀察者:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: Notification.Name("OrderAdded"), object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}