swift - ViewController 之间传递数据取决于 UIButton 的标签

标签 swift tableview segue

我有 UITableView,并将选定的 Item 从一个 UIViewController 传递到另一个。为了实现这一点,我有 Item 对象数组。

var array = [Item]()

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

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

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

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

然后在 ViewController 的 prepare 方法中,我将 sender 向下转换为 UIButton,然后在目标 ViewController 中分配 selectedItem 变量作为 array 中的 Item,以 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]
    }
}

问:这工作得很好,我已经使用它很长时间了,但我感觉这不是正确的解决方案。还有更好的吗?

最佳答案

我的偏好是在这里使用委托(delegate)模式。

在这种方法中, View Controller 使自己成为它创建的每个 TableView 单元格的委托(delegate)。它将 Item 传递到单元格。当点击单元格中的按钮时,单元格将 Item 发送回 View Controller 。通过这种方式, View Controller 知道哪个 Item 被选择并且应该发送到下一个 View Controller 。

要实现,首先在表格 View 单元格中声明一个变量来保存Item:

weak var item: Item?

在 View Controller 中,将项目传递到单元格:

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

接下来,声明委托(delegate)协议(protocol):

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

将这种类型的变量添加到自定义表格 View 单元格中,如下所示:

weak var delegate: ItemSelectionDelegate?

使表格 View 单元格中的按钮在点击时调用委托(delegate),并将项目传递给它:

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

现在,使您的 View Controller 符合此协议(protocol):

class MyViewController: UIViewController, ..., ItemSelectionDelegate {

    func itemSelected(_ item: Item) {
        //...
    }
}

确保将 View Controller 设置为每个单元格的委托(delegate):

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

现在将其传递给您的下一个 View Controller :

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/

相关文章:

ios - searchbarsearchbuttonclicked 未在 UICollectionViewController 中调用

ios - 实例化 Controller 时准备 segue 崩溃

Swift segue 执行了多次

ios - 如何将图像放在 UIActionSheet 上?

swift - 在 Swift 中,我是否需要在为变量创建实例后强制展开变量?

ios - Swift 实例化ViewControllerWithIdentifier

ios - swift ios 中的 tableview 详细文本标签

javafx - 在 JavaFX TableView 中插入行并开始编辑无法正常工作

ios - TableView 位于另一个 TableView 的标题内

iphone - 从 Master 到 Detail UITableView,其中第二个具有分组样式