我有 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/