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

设备旋转时UITableViewCell中UITextField值消失问题求助

解决UITableViewCell旋转时TextField值丢失的问题

这个问题我之前也遇到过,核心原因是你没有把用户输入的内容持久化到数据源里,而且当前的单元格加载方式每次都会创建新实例,导致旧cell里的输入内容随cell销毁而丢失。下面是具体的解决步骤:

一、先理清核心问题

设备旋转时,系统会重新布局视图,UITableView会再次调用cellForRowAt方法。你当前的代码每次都是通过loadNibNamed加载新的cell实例,而用户输入的文本只保存在旧cell的UITextField里,新cell自然是空的。同时,你也没有一个数据源来存储这些输入值,无法在新cell创建时把值回填回去。

二、具体解决方案

1. 创建表单数据源

首先为你的PROSPECT表单创建一个数据源,用来存储每个单元格的输入值。比如在你的UITableViewController里添加:

// 假设PROSPECT表单有5个单元格,初始化时给每个位置设为nil
private var prospectFormData: [String?] = Array(repeating: nil, count: 5)

2. 正确注册和复用Xib单元格

你之前每次加载Xib的方式会创建新cell,不符合UITableView的复用机制,应该先注册Xib,再复用cell:
在viewDidLoad里添加注册代码:

override func viewDidLoad() {
    super.viewDidLoad()
    // 注册Xib文件
    tableView.register(UINib(nibName: Constants.LOGFORM_CELL_IDENTIFIER, bundle: nil), 
                       forCellReuseIdentifier: Constants.LOGFORM_CELL_IDENTIFIER)
    tableView.register(UINib(nibName: Constants.CONTACTFORM_CELL_IDENTIFIER, bundle: nil), 
                       forCellReuseIdentifier: Constants.CONTACTFORM_CELL_IDENTIFIER)
}

然后修改cellForRowAt方法,使用复用机制:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell: UITableViewCell
    
    switch formType { 
    case .LOG: 
        cell = tableView.dequeueReusableCell(withIdentifier: Constants.LOGFORM_CELL_IDENTIFIER, for: indexPath) as! LogFormTableViewCell
        // 如果LOG表单也有输入项,同样需要从数据源赋值
    case .PROSPECT: 
        switch indexPath.row { 
        case 0: 
            cell = tableView.dequeueReusableCell(withIdentifier: Constants.LOGFORM_CELL_IDENTIFIER, for: indexPath) as! LogFormTableViewCell
        default: 
            cell = tableView.dequeueReusableCell(withIdentifier: Constants.CONTACTFORM_CELL_IDENTIFIER, for: indexPath) as! ContactFormTableViewCell
        } 
    }
    
    // 给cell的TextField赋值(从数据源取)
    configureCellContent(cell: cell, indexPath: indexPath)
    cell.selectionStyle = .none 
    return cell 
} 

3. 实现cell内容配置方法,回填数据

添加一个方法,把数据源里的值赋值给cell的TextField:

private func configureCellContent(cell: UITableViewCell, indexPath: IndexPath) {
    guard formType == .PROSPECT else { return }
    
    let row = indexPath.row
    // 设置TextField的代理和tag,方便后续保存数据
    if let logCell = cell as? LogFormTableViewCell {
        logCell.textField.text = prospectFormData[row]
        logCell.textField.delegate = self
        logCell.textField.tag = row
    } else if let contactCell = cell as? ContactFormTableViewCell {
        contactCell.textField.text = prospectFormData[row]
        contactCell.textField.delegate = self
        contactCell.textField.tag = row
    }
}

4. 实现UITextFieldDelegate,保存输入值

让你的ViewController遵守UITextFieldDelegate协议,然后实现代理方法保存输入内容:

extension YourTableViewController: UITextFieldDelegate {
    // 当用户结束编辑时,保存内容到数据源
    func textFieldDidEndEditing(_ textField: UITextField) {
        let row = textField.tag
        guard row < prospectFormData.count else { return }
        prospectFormData[row] = textField.text
    }
    
    // 点击键盘完成按钮收起键盘
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

三、为什么LOG表单正常工作?

大概率是LOG类型的表单没有可编辑的输入项,或者它的内容已经绑定到了对应的数据源,旋转时重新加载cell会自动从数据源取值,所以不会出现丢失的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:57:49