【问题标题】:How would I pass data using a closure?我将如何使用闭包传递数据?
【发布时间】:2019-11-23 14:54:33
【问题描述】:

我正在尝试使用 HomeCell 中的闭包 (addActionHandler) 将数据从 HomeViewController 中的单元格传递到 CartViewController。

我之前的工作是在 HomeVC 的 cellForRowAt 中使用 Tray.currentCart.cartItems.append(item) 传递数据。

但由于我通过删除 static let currentCart = Tray() 修改了我的 Tray 类,我似乎无法让 HomeVC 中的单元格将数据传递给 CartVC。

在 Home Cell 中按下 ATCBtn 后,如何修改代码以使其再次将数据从 HomeVc 传递到 CartVC

我非常接近我的解决方案,我只是不知道从这里到哪里使它工作......任何帮助将不胜感激

import UIKit
import Firebase
import FirebaseFirestore

class HomeViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var cartBtn: UIBarButtonItem! //segues data to CartVC

    var tray: [Tray] = []
    var itemSetup: [Items] = []
    var selectedItem: Items?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        tableView.dataSource = self
        tableView.delegate = self
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? CartViewController {
            vc.items = self.selectedItem
        }
    }
}
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemSetup.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell") as? TestCell else { return UITableViewCell() }

        let item = itemSetup[indexPath.row]
        cell.configure(withItems: item)
        cell.addActionHandler = { (option: Int) in
           print("Option selected = \(option)")
        // Tray.currentCart.cartItems.append(item) //old code that passed data for selected cell in HomeVC to cartVC
           item.selectedOption = option
        }

        return cell
    }
}

class CartViewController: UIViewController {

    var items: Items!
    var tray: [Tray] = []

    @IBOutlet weak var cartTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        cartTableView.dataSource = self
        cartTableView.delegate = self
    }
}

extension CartViewController: UITableViewDataSource, UITableViewDelegate {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell
     // let cart = Tray.currentCart.cartItems[indexPath.row] // code that was used to populate data in CartCells switched with new code below  
        let cart = tray[indexPath.row].cartItems[indexPath.section]
        cell.configure(withItems: cart)

        return cell
   }

}

class Tray {
    var cartItems = [Items]()
    var cart: Items!
    var brandName: String!
    // static let currentCart = Tray() code that has been removed
}

【问题讨论】:

  • “点击 atcBtn 时,打开带有所选项目的 cartViewController?”。这是要求吗?
  • atcBtn 不打开 CartVC 只是通过数据选择项填充 CartVC 单元格,Hom​​eVC 的 NavBar 中的 CartBtn 打开 CartVC
  • tray: CartViewController 中的 [Tray] = [] 应该从 HomeViewController 填充对吗?
  • 是的,它用于从 HomeVC 填充 CartVC 中的单元格。 var itemSetup: [Items] = [] 填充 HomeVC 的单元格。 Items 类从 cloudFirestore 中提取数据。我只是没有在问题上将 Firestore 代码放在 HomeVC 中
  • numberOfSections 始终为 1?如果是,则可以避免使用“tray[indexPath.row].cartItems[indexPath.section]”。在 HomeVC 中创建一个托盘 [] 并传递给 CartVC。除非需要,否则应避免包含 items 和 items[] 的 Class Tray。

标签: ios swift uitableview closures segue


【解决方案1】:

如下设置类托盘

class Tray {
    var cart: Items
    var brandName: String
    init(cart: Items,
         brandName: String) {
        self.cart = cart
        self.brandName = brandName
    }
}

在 HomeViewController 中,在 addActionHandler 下将选定的项目附加到购物车

cell.addActionHandler = { (option: Int) in
    print("Option selected = \(option)")
    item.selectedOption = option
    tray.append(Tray(cart: item, brandName: "<Brand Name>"))
}

将托盘[] 传递给 CartViewController

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let vc = segue.destination as? CartViewController {
        vc.items = self.selectedItem
        vc.tray = self.tray
    }
}

在 CartViewController 中,将项目传递给 cartCell

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell
     let cart = tray[indexPath.row]
     cell.configure(withItems: cart.cart)
     return cell
}

【讨论】:

  • 我得到的唯一问题是在 CartVC cellForRowAt cell.configure(withItems: cart) 中,错误代码为 无法将“托盘”类型的值转换为预期的参数类型“项目”
  • 哦等等!我得到了它的工作!:) 在 cellForRowAt 的 HomeVC 中我做了 self. tray.append(Tray(cart: item, brandName: "" )) 在 CartVC cellForRowAt 我做了这个 cell.configure(withItems: cart .cart ) 如果我这样做可以吗?或者它会在以后继续编码时给我带来问题,因为当数据在单元格中传递时,我将转换它以将其分成多个部分
  • cell.configure(withItems: cart .cart)。这是正确的,解决方案已更新。它不会产生问题。如果您需要添加更多部分,请相应地更改班级托盘。我很高兴为您找到解决方案:)
  • 非常感谢@Dili 哦,好吧,我不知道我必须修改托盘类才能将部分添加到 CartVC。
  • 如果有更多部分。创建一个截面模型,如 struct SectionModel { var title: String var rowItems: [Tray] }。并使用 [SectionModel] 作为 tableview 的 dataArray
猜你喜欢
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2021-10-23
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
相关资源
最近更新 更多