我已经UITableView,并且正在将选定的Item从一个UIViewController传递到另一个。为此,我有Item对象数组。

var array = [Item]()


为了执行segue,我将sender操作的buttonPressed参数作为sender方法的performSegue传递。

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


此按钮在UITableViewCell内部,并具有等于indexPath.row的标记,该标记是我在TableView cellForRowAt数据源方法中设置的:

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


然后在ViewController的prepare方法中,将sender下调为UIButton,然后从selectedItem中将Item用作索引,将目标ViewController中的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]
    }
}


问:这很好用,我已经使用了很长时间,但是我感觉这不是正确的解决方案。有没有更好的办法?

最佳答案

我的首选是在这里使用委托模式。

在这种方法中,视图控制器使自己成为其创建的每个tableview单元的委托。它将Item传递到单元格。轻按单元格中的按钮后,单元格会将Item发送回视图控制器。通过这种方式,视图控制器知道选择了哪个Item,应该将其发送到下一个视图控制器。

要实现,首先要在表视图单元格中声明一个变量来保存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?


轻击时,使表视图单元格中的按钮调用委托,并将其传递给项目:

@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,但通过Item而不是按钮:

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
    }
}


这绝对是设置工作,因此,仅在对您有意义的情况下使用。

关于swift - 在ViewController之间传递数据取决于UIButton的标签,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53627101/

10-16 14:07