代码之家  ›  专栏  ›  技术社区  ›  Robert Dresler Gustavo Vollbrecht

在ViewController之间传递数据取决于UIButton的标记

  •  0
  • Robert Dresler Gustavo Vollbrecht  · 技术社区  · 6 年前

    UITableView 我通过了选拔赛 Item 从一开始 UIViewController 项目 物体。

    var array = [Item]()
    

    为了表演赛格,我通过了 sender buttonPressed 作为行动 属于 performSegue

    @IBAction func buttonPressed(_ sender: UIButton) {
        performSegue(withIdentifier: "identifier", sender: sender)
    }
    

    这个按钮在里面 UITableViewCell 并且具有等于的标记 indexPath.row cellForRowAt 数据源方法:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        ...
        cell.myButton.tag = indexPath.row
        ...
    }
    

    然后在ViewController的 prepare 方法一沮丧 作为 UIButton 然后我分配 selectedItem 项目 从…起 array button.tag

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "identifier" {
            let button = sender as! UIButton
            let destinationVC = segue.destination as! ViewController2
            destinationVC.selectedItem = array[button.tag]
        }
    }
    

    问: 这个很好用,我用了很长时间,但我觉得这不是正确的解决方案。还有更好的吗?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Mike Taverne    6 年前

    在这种方法中,视图控制器使自己成为它创建的每个tableview单元的委托。它通过了 Item 去牢房。当点击单元格中的按钮时,单元格将发送 项目 返回视图控制器。通过这种方式,视图控制器知道 项目 已选择,应发送到下一个视图控制器。

    项目

    weak var item: Item?
    

    在视图控制器中,将项目传递到单元格:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //...
        cell.item = array[indexPath.row]
        //...
    }
    

    接下来,声明一个委托协议:

    protocol ItemSelectionDelegate {
        func itemSelected(_ item: Item)
    }
    

    weak var delegate: ItemSelectionDelegate?
    

    使tableview单元格中的按钮在点击时调用代理,并将项目传递给它:

    @IBAction func buttonPressed(_ sender: UIButton) {
        if let item = item {
            delegate?.itemSelected(item)
        }
    }
    

    现在,使视图控制器符合此协议:

    class MyViewController: UIViewController, ..., ItemSelectionDelegate {
    
        func itemSelected(_ item: Item) {
            //...
        }
    }
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //...
        cell.item = array[indexPath.row]
        cell.delegate = self
        //...
    }
    

    打电话给你的segue,但把电话传过去 项目 而不是按钮:

    class MyViewController: UIViewController, ..., ItemSelectionDelegate {
    
        func itemSelected(_ item: Item) {
            performSegue(withIdentifier: "identifier", sender: item)
        }
    }
    

    现在将其传递给下一个视图控制器:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "identifier" {
            let destinationVC = segue.destination as! ViewController2
            destinationVC.selectedItem = sender as? Item
        }
    }
    

        2
  •  -1
  •   alitosuner    6 年前

    若我并没有弄错,那个么您必须将选定的索引路径行放入 prepareForSegue :

        if segue.identifier == "identifier" {
            guard let destinationVC = segue.destination as? ViewController2 else { return }
            guard let selectedIndexPath = self.tableView.indexPathForSelectedRow else { return }
            destinationVC.selectedItem = selectedIndexPath.row 
        }