即使在删除某些单元格后,仍以与 TableView 单元格相同的顺序将文本字段值保存在数组中

Posted

技术标签:

【中文标题】即使在删除某些单元格后,仍以与 TableView 单元格相同的顺序将文本字段值保存在数组中【英文标题】:Saving textfield values in array in the same order as TableView Cell even after some cells are deleted 【发布时间】:2016-04-12 14:27:35 【问题描述】:

我有一个 TableView,允许用户添加单元格以进行文本输入。

我实现了文本字段委托方法,它观察单元格文本字段中的变化并将文本值存储在数组中。

我目前将 cellForRowAtIndexPath 方法的indexPath.row 分配为单元格文本字段的标记值。我使用该标签作为数组的索引来更新值。

但是,一旦我删除一些单元格并添加新单元格来存储新值,这种方法就会出现问题。值存储在数组的随机索引中。

即使删除了某些单元格,如何以与表格单元格相同的索引顺序保存数组中的值?

var stepCount = 1
var stepOrder = ["1"]
var steps = [""]

@IBAction func stepTextFieldDidChange(sender: UITextField) 
    steps[stepTextField.tag] = sender.text!


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    var cell:UITableViewCell?

    if tableView == self.stepTableView 
        let aCell = tableView.dequeueReusableCellWithIdentifier("StepCell", forIndexPath: indexPath) as! StepCell
        stepTextField = aCell.getTextField()
        stepTextField.tag = indexPath.row
        aCell.stepTextField.delegate = self
        aCell.configureStepCell(stepOrder[indexPath.row], step: steps[indexPath.row])
        cell = aCell
    

    return cell


func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 
    if tableView == stepTableView 

        if editingStyle == .Delete 
            // Delete the row from the data source
            if stepOrder.count > 1 
                steps.removeAtIndex(indexPath.row)
                stepTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
                stepTableView.reloadData()
               
         else if editingStyle == .Insert 
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        
    


@IBAction func addStep(sender: AnyObject) 
    stepCount++
    stepOrder.append("\(stepCount)")
    steps.append("")
    stepTextField.becomeFirstResponder()
    stepTableView.reloadData()

【问题讨论】:

您是否遗漏了cellForRowAtIndexPath 的代码?我看不出它会如何编译。此外,即使单元格已被删除,您是否希望存储文本值?我不确定我是否理解这个问题。 @Caleb 你说得对,为了简洁起见,我从源代码中省略了一些代码。我已经用原始源更新了那个代码块。我不想存储已删除的值。当重新开始比编辑更容易时,用户会删除一个单元格并添加一个新单元格。我需要存储新单元格中的新值,但删除单元格后我当前的实现无法正确存储。 我没有看到 cellForRow.. 或删除逻辑有任何明显错误。你的插入逻辑是什么样的?另外,这些值是在删除后立即出现错误顺序,还是仅在插入新值后出现? 在按下add step 后,它们会以错误的顺序混合。我用那个函数更新了问题。 所以删除工作正常吗?你的插入代码在哪里? 【参考方案1】:

使用标签很困难,因为正如您所发现的,索引会随着您操作表格数据而改变。

虽然对于一个简单的字符串来说有点开销,但我会创建一个Step 类并存储一个数组。然后,您可以在自定义单元格中存储对 Step 实例的引用,并从您的委托方法更新它。

关于委托的主题,您应该将 UITextField 委托方法移动到您的单元类中,并提供一个新协议让您的视图控制器知道更改。

class Step 
    var stepValue = ""

    convenience init(_ value:String) 
        self.init()
        self.stepValue=value
    


protocol StepDelegate 
    func stepValueChanged(step:Step, newValue:String) -> Void


In your cell class you will have:

var delegate : StepDelegate?
var step: Step!

func stepTextFieldDidChange(sender: UITextField) 
    self.step.stepValue = = sender.text!
    self.delegate?.stepValueChanged(self.step,newValue:self.step.stepValue)

在您的视图控制器中,您将拥有:

var steps = [Step]()

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    var cell:UITableViewCell?

    if tableView == self.stepTableView 
        let aCell = tableView.dequeueReusableCellWithIdentifier("StepCell", forIndexPath: indexPath) as! StepCell

        let step=self.steps[indexPath.row]

        aCell.delegate=self
        aCell.step=step

        aCell.configureStepCell(step)
        cell = aCell
    

    return cell


func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 
    if tableView == stepTableView 

        if editingStyle == .Delete 
            // Delete the row from the data source
                steps.removeAtIndex(indexPath.row)
                stepTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
         else if editingStyle == .Insert 
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        
    


@IBAction func addStep(sender: AnyObject) 

    let newStep=Step("\(self.steps.count+1)")
    let newPath=NSIndexPath(forRow: self.steps.count, inSection: 0)
    steps.append(newStep)
    self.stepTableView.insertRowsAtIndexPaths([newPath], withRowAnimation: .Automatic)


func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 
    if (self.steps.count > 1) 
        return .Delete 
     else 
        return .None     // Don't allow deletion of the last item in the table
    

【讨论】:

为简单起见,我省略了stepCount 的东西;无论如何,您应该能够从数组中的索引确定这一点 非常感谢。你能解释一下这是干什么用的吗? self.delegate?.stepValueChanged(self.step,newValue:self.step.stepValue) 也不确定这个 newValue 是如何确定的。为什么需要aCell.step=step 该行调用视图控制器中的委托方法来告诉它值已更改。新值的确定与现在相同;通过调用stepValueDidChange 的东西,除了该方法现在在您的tableview 单元类中而不是在视图控制器中。例如,这可以由文本字段委托方法调用。 aCell.step=step 将对Step 实例的引用放入单元类中,以便它可以直接更新数据模型 在视图控制器中,将步骤(类类型数组)的值转换为字符串的最佳方法是什么?我最初的实现使用了一个普通数组,我可以简单地映射到字符串,但在这种情况下不确定。执行 for 循环并将值连接到字符串? 我是否需要像 class ViewController: .... , StepDelegate 这样将 StepDelegate 添加到 ViewController 类声明中?没有它,我在aCell.delegate=self 上遇到错误。但即使声明,我仍然得到ViewController does not conform to protocol 'StepDelegate'

以上是关于即使在删除某些单元格后,仍以与 TableView 单元格相同的顺序将文本字段值保存在数组中的主要内容,如果未能解决你的问题,请参考以下文章

从 UITableView 插入/删除单元格后的 IndexPath 错误

在 tableView 中选择单元格后布局更改

在 TableView 中创建的 7 个单元格后添加部分 - Swift

如何在swift 4中重新排序单元格后保存tableView顺序

无法识别单击单元格后的 tableView segue

单击表格单元格后,QtableView 中的某些单元格不会自动重绘