ios - 在 Swift 的 UITextfield 中滚动 Tableview 数据重新洗牌
问题描述
我有表格视图,其中单元格由多个部分组成,每个部分有不同的行数,每行都有一个文本字段。当我在其中写入并向下和向上滚动时,数据丢失或重新排列。所以我试图将文本字段数据保存到二维数组中,但我无法解决这个问题。
这是自定义单元格中的代码:
class CustomCell: UITableViewCell {
@IBOutlet weak var userName: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
查看控制器代码:
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel()
label.text = "Header"
return label
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 7
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableview.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath) as! CustomCell
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80.0
}
}
解决方案
UITextField
您的单元格一旦超出表格视图的可见范围就会从内存中删除,因此不能期望它们保留数据(您的内容)。
您必须查看UITableViewDataSource
协议并将单元格的内容存储UITextFields
在一个类中,该类将在您的表格视图的视图控制器的持续时间内保留在内存中。
通常,人们使用视图控制器作为数据源,就像您所做的那样。
步骤如下:
- 在视图控制器的初始化中,创建并准备一个数据结构(以 IndexPaths 为键的数组/字典),它将包含您需要存储的文本内容
- 将单元格出列时(在您的
cellForRowAt
函数中),如果该特定 indexPath 的内容存在,请使用数据结构中的必要字符串配置单元格。 - 当用户在单元格中更改文本时,通知您的数据源单元格索引路径的新内容
例子:
定义以下协议:
protocol DataSourceUpdateDelegate: class {
func didUpdateDataIn(_ sender: UITableViewCell, with text: String?)
}
确保您UITableViewCell
声明一个委托变量并使用它:
class MyCell: UITableViewCell, UITextFieldDelegate {
@IBOutlet var myTextField: UITextField!
weak var dataSourceDelegate: DataSourceUpdateDelegate?
func configureCellWithData(_ data: String?, delegate: DataSourceUpdateDelegate?)
{
myTextField.text = data
myTextField.delegate = self
dataSourceDelegate = delegate
}
override func prepareForReuse() {
myTextField.text = ""
super.prepareForReuse()
}
func textFieldDidEndEditing(_ textField: UITextField) {
dataSourceDelegate?.didUpdateDataIn(self, with: textField.text)
}
}
确保您的 View Controller 符合DataSourceUpdateDelegate
并初始化一个变量来管理数据:
class MyViewController: UITableViewController, UITableViewDataSource, DataSourceUpdateDelegate {
var data = [IndexPath : String]()
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = MyCell() // Dequeue your cell here instead of instantiating it like this
let cellData = data[indexPath]
cell.configureCellWithData(cellData, delegate: self)
return cell
}
func didUpdateDataIn(_ sender: UITableViewCell, with text: String?) {
data[tableView.indexPath(for: sender)!] = text
}
}
推荐阅读
- cassandra - 在 cassandra 中对 1 列运行批量更新查询
- mysql - mysql`听起来`没有返回所有正确/预期的结果
- javascript - 在同一页面上提交带有成功/失败警报的联系表
- c# - ASP.NET Core DI:如何在不指定类型的情况下通过 lambda 注入服务
- mysql - 按月返回默认值 1 的 MySQL 交叉表查询?
- vba - 打开表单后如何在 Word 文档末尾添加子文档?
- vba - 删除 Power Point 幻灯片中的现有图表并使用 VBA 替换为新图表
- django - 为 django 应用程序添加安全标头的最佳做法是什么?
- c# - 无法使用淘汰组件呈现部分 html
- visual-studio - 应用程序链接到 msvcp140d 而不是 msvcp140