swift - 在 ViewController 之间传递数据依赖于 UIButton 的标签
问题描述
我已经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
我在 TableViewcellForRowAt
数据源方法中设置的标签:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.myButton.tag = indexPath.row
...
}
然后在 ViewController 的prepare
方法中我向下转换sender
为UIButton
,然后我在目标 ViewController 中分配变量作为selectedItem
索引。Item
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
}
}
这肯定需要更多的设置工作,所以只有在对您有意义的情况下才使用。
推荐阅读
- ssl - 我所有的网站都返回 301 而不是 200
- postgresql - 分组选择第 n 行 Postgres
- c# - 更新控件属性会破坏 OneWay 绑定?
- elixir - Ecto - 自动大写字段
- typescript - 转换为函数时无法编译代码
- ruby-on-rails - 查找关联记录仅具有特定属性值的所有记录
- java - If 语句 - 空安全的可变顺序
- java - isDisplayable(),isShowing(),isVisible() 为 JDialog 提供错误值
- python-3.x - 显式 __init__ python
- css - 如何循环一组动画,即每行在css动画中弹跳一次?