You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据TableView选中的单元格修改字典数组中的对应元素值

最优方案是通过闭包建立反向数据回传链路,同时修改数据模型的可变性,具体实现步骤如下:

问题根源

  • 你的TradeList中的trades数组用let声明,本身就不允许修改
  • Trade和TradeList都是结构体(值类型),页面间传递的是数据副本,修改副本不会影响主页面的原数组
  • 没有建立数据回传链路,编辑后的新数据无法传递回主页面更新原数组

步骤1:修改数据模型,支持数据修改

首先确保Trade结构体的属性为可修改的var,同时把TradeList中的trades改为var:

// Trade 结构体示例(如果原来属性是let要改成var)
struct Trade {
    var ticker: String
    var name: String
}

// 修改TradeList
struct TradeList {
    // 把let改为var,支持修改数组内容
    var trades: [Trade] = [
        Trade(ticker: "AAPL", name: "Apple"),
        Trade(ticker: "AMD", name: "Advanced Micro Devices")
    ]
}

步骤2:给EditViewController添加保存回调

在EditViewController中新增闭包属性,点击保存时将新数据通过闭包传出:

class EditViewController: UIViewController {
    var editTitle: String?
    var editPrice: String?
    // 新增保存回调,参数为修改后的代码和名称
    var saveCompletion: ((_ newTicker: String, _ newName: String) -> Void)?

    @IBOutlet weak var editTitleField: UITextField!
    @IBOutlet weak var editPriceField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        editTitleField.text = editTitle
        editPriceField.text = editPrice
    }

    @IBAction func editSaveButton(_ sender: UIButton) {
        guard let newTicker = editTitleField.text, !newTicker.isEmpty,
              let newName = editPriceField.text, !newName.isEmpty else {
            // 可自行添加输入为空的提示逻辑
            return
        }
        // 传出新数据
        saveCompletion?(newTicker, newName)
        dismiss(animated: true)
    }
}

步骤3:给DetailViewController新增属性和回调

在DetailViewController中新增存储选中下标的属性,以及编辑完成的回调,同时在跳转EditViewController时接收保存回调:

class DetailViewController: UIViewController {
    let trade: Trade
    // 新增:存储当前数据在数组中的下标
    var selectedIndex: Int!
    // 新增:编辑完成回调,参数为下标、新代码、新名称
    var editCompletion: ((_ index: Int, _ newTicker: String, _ newName: String) -> Void)?

    @IBOutlet var tickerLabel: UILabel!
    @IBOutlet var nameLabel: UILabel!

    // 原有初始化、viewDidLoad等代码不变...

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "DetailVCToEditVC" {
            let displayVC = segue.destination as! EditViewController
            displayVC.editTitle = tickerLabel.text
            displayVC.editPrice = nameLabel.text
            // 接收编辑页的保存回调
            displayVC.saveCompletion = { [weak self] newTicker, newName in
                guard let self = self else { return }
                // 更新当前详情页显示
                self.tickerLabel.text = newTicker
                self.nameLabel.text = newName
                // 把新数据和下标传给主页面
                self.editCompletion?(self.selectedIndex, newTicker, newName)
            }
        }
    }
}

步骤4:主ViewController接收回调,更新数组和表格

修改主ViewController的segue方法,给DetailViewController的回调赋值,收到新数据后更新原数组,刷新对应表格行:

@IBSegueAction func showDetailView(_ coder: NSCoder) -> DetailViewController? {
    guard let indexPath = tradeTableView.indexPathForSelectedRow
    else { fatalError("Nothing selected!")}
    
    let trade = tradesList.trades[indexPath.row]
    let detailVC = DetailViewController(coder: coder, trade: trade)
    // 传入选中行的下标
    detailVC?.selectedIndex = indexPath.row
    // 接收编辑完成的回调
    detailVC?.editCompletion = { [weak self] index, newTicker, newName in
        guard let self = self else { return }
        // 更新原数组对应位置的数据
        self.tradesList.trades[index].ticker = newTicker
        self.tradesList.trades[index].name = newName
        // 只刷新对应行,性能更好
        self.tradeTableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
    }
    return detailVC
}

这种方案是iOS页面间反向传值的标准最优实现,逻辑清晰耦合度低,不需要用到通知、单例等高耦合的方案。

内容的提问来源于stack exchange,提问作者kriskrossy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 20:24:02