设备旋转时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
相关产品推荐
相关产品推荐

