【问题标题】:Have error "Invalid update: invalid number of rows" when I already updated the data当我已经更新数据时出现错误“无效更新:无效行数”
【发布时间】:2016-12-06 21:40:40
【问题描述】:

我的代码如下所示:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    let IndexPaths = NSArray(array:[indexPath])

    let plistPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = plistPath.appending("/ClassA.plist")
    self.listClasses.remove(at:indexPath.row)
    self.listClasses?.write(toFile: path, atomically: false)
    tableView.reloadData()
    self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)
}

我知道如果我不更新数据源中的数据会导致问题,所以我在更新 TableView 中的数据之前添加了这两行。

self.listClasses.remove(at:indexPath.row)
self.listClasses?.write(toFile: path, atomically: false)

但它仍然不起作用。我仍然收到此错误

'无效更新:第0节中的行数无效。更新后现有节中包含的行数(6)必须等于更新前该节中包含的行数(6),加上或减去从该节插入或删除的行数(0 插入,1 删除),加上或减去移入或移出该节的行数(0 移入,0 移出)。

有人知道为什么会这样吗?

下面是我的 TableView 代码

@IBAction func Edit(_ sender: Any) {
    setEditing(true, animated: true)
}

func tableView(_ tableView:UITableView, numberOfRowsInSection     selection:Int) -> Int {
    return self.listClasses.count
}

public func tableView(_ tableView: UITableView, cellForRowAt indexPath:IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath as IndexPath)
    let row = indexPath.row

    let rowDict = self.listClasses[row] as! NSDictionary

    cell.textLabel?.text = rowDict["name"] as? String
    return cell
}

override func viewDidLoad() {
    // Do any additional setup after loading the view, typically from a nib.
    super.viewDidLoad()

    let plistPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = plistPath.appending("/ClassA.plist")
    let fileManager = FileManager.default
    if (!(fileManager.fileExists(atPath: path)))
    {
        let bundle : String = Bundle.main.path(forResource: "ClassA", ofType: "plist")!
        do {
            try fileManager.copyItem(atPath: bundle as String, toPath: path)
        }
        catch {
            NSLog("Error!")
        }
    }
    self.listClasses = NSMutableArray(contentsOfFile:path)

    //set up the textfield
    self.txtField.isHidden = true
    self.txtField.delegate = self

}

override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)
    self.tableView.setEditing(editing, animated:true)
}

//更新 现在我删除了“tableView.reloadData()”

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    let IndexPaths = NSArray(array:[indexPath])

    let plistPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = plistPath.appending("/ClassA.plist")
    self.listClasses.remove(at:indexPath.row)
    self.listClasses?.write(toFile: path, atomically: false)
    self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)
}

但还是不行。

【问题讨论】:

  • either call reloadData or call deleteRows not both.
  • @Paulw11 我试图删除其中一个(两种方式),但它仍然不起作用。
  • 不,这是对所示代码的修复;您是否在其他地方删除该行?如果您删除 deleteRows,留下 reloadData 并且您仍然收到该消息,那么您将删除其他地方,因为 reloadData 永远不会导致该异常

标签: ios swift uitableview


【解决方案1】:

你有:

tableView.reloadData()
self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)

永远不要两者都做。只做其中之一。在这种情况下,最好这样做:

self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)

【讨论】:

  • 这个方法应该在tableView.beginUpdates()和endUpdates()之间调用。不是吗?
  • @BhavukJain 不,如果你多次调用delete/insert/reloadRows 的组合,你只需要使用begin/endUpdate
  • @David 我建议的更改将解决问题。您是否删除了对reloadData 的呼叫?删除那行代码后的新错误是什么?
  • 还是一样。 "'无效更新:第0节中的行数无效。更新后现有节中包含的行数(6)必须等于更新前该节中包含的行数(6),加或减从该部分插入或删除的行数(0 插入,1 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。我在我的问题上发布了我的新代码。
  • 这毫无意义。您显然正在为self.listClasses 删除一个对象,而您的numberOfRowsInSection 是基于self.listClasses。作为健全性检查,使用调试器查看在调用self.listClasses.remove(at:indexPath.row) 之前和之后self.listClasses 中的对象数量。你看到了什么?
【解决方案2】:
extension UITableView {
     var dataHasChanged: Bool {
        guard let dataSource = dataSource else { return false }
        let sections = dataSource.numberOfSections?(in: self) ?? 0
        if numberOfSections != sections { return true }

        for section in 0..<sections {
            if numberOfRows(inSection: section) != dataSource.tableView(self, numberOfRowsInSection: section) {
                return true
            }
        }

        return false
     }
}

用法:

 if tableView.dataHasChanged {
     tableView.reloadData()
 } else {
     // Do anything what you want here
     // tableView.deleteRows(at: [indexPath], with: .none)
     // tableView.reloadRows(at: [indexPath], with: .none)
 }

【讨论】:

    猜你喜欢
    • 2022-01-12
    • 2016-11-30
    • 1970-01-01
    • 2015-07-01
    • 2013-07-10
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    相关资源
    最近更新 更多