Ios 即使在删除某些单元格后,仍按与TableView单元格相同的顺序在数组中保存textfield值

Ios 即使在删除某些单元格后,仍按与TableView单元格相同的顺序在数组中保存textfield值,ios,swift,uitableview,Ios,Swift,Uitableview,我有一个TableView,允许用户为文本输入添加单元格 我实现了textfield委托方法,该方法监视单元格textfield中的更改,并将文本值存储在数组中 我当前将CellForRowatineXpath方法的indexPath.row指定为单元格文本字段的标记值。我使用该标记作为数组的索引来更新值 但一旦我删除一些单元格并添加新单元格以存储新值,这种方法就会引起问题。值存储在数组的随机索引中 即使删除了某些单元格,如何在数组中以与表单元格相同的索引顺序保存值 var stepCount

我有一个TableView,允许用户为文本输入添加单元格

我实现了textfield委托方法,该方法监视单元格textfield中的更改,并将文本值存储在数组中

我当前将CellForRowatineXpath方法的
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()
}

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

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

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

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

您是否遗漏了
单元格中的代码,如rowatinexpath
?我不知道它将如何编译。此外,即使单元格已删除,您是否希望存储文本值?我不确定我是否理解这个问题。@Caleb你是对的,为了简洁起见,我遗漏了一些源代码。我已经用原始源代码更新了那个代码块。我不想存储已删除的值。当重新开始比编辑更容易时,用户会删除一个单元格并添加一个新单元格。我需要存储新单元格中的新值,但删除单元格后,我当前的实现无法正确存储。我看不出cellForRow有任何明显的错误。。或删除逻辑。您的插入逻辑是什么样子的?此外,值是在删除后立即按错误的顺序排列,还是仅在插入新值后才按错误的顺序排列?在按下
add step
后,它们会按错误的顺序混合。我用这个函数更新了这个问题。所以删除可以吗?插入代码在哪里?为了简单起见,我省略了
stepCount
内容;您应该能够从数组中的索引中确定这一点,非常感谢。你能解释一下这是干什么用的吗<代码>self.delegate?.stepValueChanged(self.step,newValue:self.step.stepValue)不确定如何确定此新值。为什么需要
aCell.step=step
?该行调用视图控制器中的委托方法,告诉它值已更改。新值的确定与现在相同;通过调用
stepValueDidChange
,除了该方法现在在tableview单元格类中而不是视图控制器中之外。例如,这可以由文本字段委托方法调用。
aCell.step=step
将对
step
实例的引用放入cell类中,以便它可以直接在viewcontroller中更新数据模型。将step(类类型数组)的值转换为字符串的最佳方法是什么?我最初的实现使用了一个普通数组,我可以简单地映射到字符串,但在本例中不确定。是否执行for循环并将值连接到字符串?是否需要向ViewController类声明添加
StepDelegate
,如
class ViewController:,StepDelegate
?没有它,我在
aCell.delegate=self
上出错。但即使声明,我仍然得到
ViewController不符合协议“stepdegate”