在 Swift 的 UITextfield 中滚动 Tableview 数据重新洗牌

Scrolling Tableview data reshuffle in UITextfield in Swift

提问人:link786 提问时间:12/30/2018 最后编辑:manikallink786 更新时间:12/30/2018 访问量:896

问:

我有表格视图,其中单元格由多个部分组成,每个部分都有不同的行数,每行都有一个文本字段。当我在其中写下并向下和向上滚动数据时,数据丢失或重新洗牌。所以我正在尝试将文本字段数据保存到二维数组中,但我无法解决这个问题。

下面是自定义单元格中的代码:

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
    }
}
iOS iPhone Swift UITableView UIscrollView

评论


答:

1赞 FJ de Brienne 12/30/2018 #1

不能指望您的单元格保留数据(您的内容),因为一旦它们超出表视图的可见范围,它们就会从内存中删除。UITextField

您必须查看协议并将单元格的内容存储在一个类中,该类将在表视图的视图控制器期间保留在内存中。UITableViewDataSourceUITextFields

通常,人们会像您一样使用视图控制器作为数据源。

步骤如下:

  • 在视图控制器的初始化中,创建并准备一个数据结构(在 IndexPath 上键控的数组/字典),该结构将包含您需要存储的文本的内容
  • 在对单元格(在函数中)进行出列时,如果该特定 indexPath 存在内容,请使用数据结构中的必要字符串配置单元格。cellForRowAt
  • 当用户更改单元格中的文本时,请通知数据源单元格索引路径的新内容

例:

定义以下协议:

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
    }
}

评论

0赞 link786 12/30/2018
我使用了相同的过程,并通过帮助此链接 stackoverflow.com/a/41707184/7405878 在一个部分行中修复了问题,但在使用多个部分时则没有。
0赞 FJ de Brienne 12/30/2018
@link786该解决方案定义了一个单维数组来存储单元格数据。由于您有多个部分,因此在 indexPath 上键入的字典会更好用。但是,最好的解决方案是让单元格具有自定义委托,该委托会通知数据源有关更改的信息。
0赞 link786 12/30/2018
我试过了,但我似乎想不通。你能给我一些示例代码吗,那就太好了!