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

TableView仅添加单个单元格求助:触发Unwind Segue无法动态新增单元格

问题描述

每次触发unwind segue时,想给表格动态添加新单元格,但目前仅能创建一个单元格,无法定位问题原因。尝试实现delegate和data source时出现冗余错误。开发环境使用Storyboard。


视图控制器2(NewPasswordViewController)

class NewPasswordViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}

var passName:String?
var passWord:String?


//var passWordDataArray:[Password]

var NewPassWord = Password()
    


@IBAction func getPassWordName(_ sender: UITextField) {
    passName = sender.text
    if passName != nil{
        NewPassWord.name = passName!
    }
}
@IBAction func getPassWord(_ sender: UITextField) {
    passWord = sender.text
    if passWord != nil{
        NewPassWord.password = passWord!
    }
}


@IBAction func saveNewPassWord(_ sender: UIButton) {
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?)  {
    
    let vc = segue.destination as! PassWordTableViewController
    
    vc.passwords.append(NewPassWord)
    
 }

}

视图控制器1(PassWordTableViewController)

class PassWordTableViewController: UITableViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    var passwords = [Password]()

    override func numberOfSections(in tableView: UITableView) -> Int {
        return passwords.count
    }

    // return the number of rows for the table
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return passwords.count
    }
    // Provide a cell for each row
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        // Fetch a cell of the appropriate type.
        let cell = tableView.dequeueReusableCell(withIdentifier:"cell", for: indexPath) as! PassWordViewCell
        
        let thePassWord = passwords[indexPath.row]

        //Configure the cell's contents.
        cell.passWordName?.text = thePassWord.name
        
        return cell
    }
    
    @IBAction func unWindToPassWordTable(unWindSegue: UIStoryboardSegue){
        
    }
    
    }

问题分析与修复方案

核心问题1:表格数据源逻辑错误

当前numberOfSections返回passwords.count,意味着每条密码对应一个分组,且每个分组的行数等于密码数组总长度,完全不符合“单分组多行”的需求。正确逻辑:

  • numberOfSections返回1(仅一个分组)
  • numberOfRowsInSection返回passwords.count(分组行数等于数据量)

核心问题2:添加数据后未刷新表格

往数组添加新数据后,未通知表格刷新,导致界面不更新。

核心问题3:复用同一个Password实例

每次保存都使用同一个NewPassWord对象,会导致数组内元素指向同一实例,后续修改会覆盖旧数据,需每次保存时新建实例。


修复后的代码

视图控制器2(NewPasswordViewController)

class NewPasswordViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    var passName: String?
    var passWord: String?

    @IBAction func getPassWordName(_ sender: UITextField) {
        passName = sender.text
    }
    
    @IBAction func getPassWord(_ sender: UITextField) {
        passWord = sender.text
    }

    @IBAction func saveNewPassWord(_ sender: UIButton) {
        // 触发unwind segue,需确保Storyboard中已给segue设置identifier为"unwindToPasswordTable"
        performSegue(withIdentifier: "unwindToPasswordTable", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)  {
        // 校验数据有效性,避免空值
        guard let vc = segue.destination as? PassWordTableViewController,
              let name = passName, !name.isEmpty,
              let password = passWord, !password.isEmpty else {
            return
        }
        // 每次新建Password实例
        let newPassword = Password()
        newPassword.name = name
        newPassword.password = password
        vc.passwords.append(newPassword)
    }
}

视图控制器1(PassWordTableViewController)

class PassWordTableViewController: UITableViewController {
    
    var passwords = [Password]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // 若Storyboard已设置单元格identifier,此步可省略
        tableView.register(PassWordViewCell.self, forCellReuseIdentifier: "cell")
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        // 仅一个分组
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // 行数等于数据量
        return passwords.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier:"cell", for: indexPath) as! PassWordViewCell
        let thePassWord = passwords[indexPath.row]
        cell.passWordName?.text = thePassWord.name
        return cell
    }

    @IBAction func unWindToPassWordTable(unWindSegue: UIStoryboardSegue){
        // 数据更新后刷新表格
        tableView.reloadData()
    }
}

额外注意事项

  1. 确保Storyboard中已正确关联unwind segue:将NewPasswordViewController的保存按钮拖到视图控制器顶部的Exit图标,选择unWindToPassWordTable方法,并给该segue设置identifier为unwindToPasswordTable。
  2. 确保Password模型类可正常实例化,示例如下:
class Password {
    var name: String = ""
    var password: String = ""
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:54:22