我遵循了此处提供的所有步骤:The proper way to delete rows from UITableView and update array from NSUserDefaults in Swift / iOS
但是,会导致错误,说;
'无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (2) 必须等于更新前该节中包含的行数 (2),加上或减去从该部分插入或删除的行数(0 插入,1 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。
我创造了
类 TableViewController: UITableViewController {
struct Section {
var sectionName: String!
var words: [String]!
init(title: String, word: [String]) {
self.sectionName = title
self.words = word
}
}
var arrayForRows = [String]()
var sections = [Section]()
func getData() -> [String] {
if let data = userDefaultDataSave.stringArray(forKey: "data") {
return data
}
return []
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
guard let data = dataDefaults.stringArray(forKey: "data") else {
return
}
arrayForRows = data as [String]
tableView.reloadData()
sections = [
Section(title: "A", word: []), // 1
Section(title: "B", word: []), //2
Section(title: "C", word: []),
Section(title: "D", word: []),
Section(title: "E", word: []),
Section(title: "F", word: []),
Section(title: "G", word: []),
Section(title: "H", word: []),
Section(title: "I", word: []),
Section(title: "J", word: []),
Section(title: "K", word: []),
Section(title: "L", word: []),
Section(title: "M", word: []),
Section(title: "N", word: []),
Section(title: "O", word: []),
Section(title: "P", word: []),
Section(title: "Q", word: []),
Section(title: "R", word: []),
Section(title: "S", word: []),
Section(title: "T", word: []),
Section(title: "U", word: []),
Section(title: "V", word: []),
Section(title: "W", word: []),
Section(title: "X", word: []),
Section(title: "Y", word: []),
Section(title: "Z", word: [])
]
let getAlphabetData = getData()
for a in getAlphabetData {
if a.hasPrefix("A") || a.hasPrefix("a") {
if sections[0].sectionName == "A" {
sections[0].words.append(a as String)
}
}
if a.hasPrefix("B") || a.hasPrefix("b") {
if sections[1].sectionName == "B" {
sections[1].words.append(a as String)
}
}
if a.hasPrefix("c") || a.hasPrefix("c") {
if sections[2].sectionName == "C" {
sections[2].words.append(a as String)
}
}
if a.hasPrefix("D") || a.hasPrefix("d") {
if sections[3].sectionName == "D" {
sections[3].words.append(a as String)
}
}
if a.hasPrefix("E") || a.hasPrefix("e") {
if sections[4].sectionName == "E" {
sections[4].words.append(a as String)
}
}
if a.hasPrefix("F") || a.hasPrefix("f") {
if sections[5].sectionName == "F" {
sections[5].words.append(a as String)
}
}
if a.hasPrefix("G") || a.hasPrefix("g") {
if sections[6].sectionName == "G" {
sections[6].words.append(a as String)
}
}
if a.hasPrefix("H") || a.hasPrefix("h") {
if sections[7].sectionName == "H" {
sections[7].words.append(a as String)
}
}
if a.hasPrefix("I") || a.hasPrefix("i") {
if sections[8].sectionName == "I" {
sections[8].words.append(a as String)
}
}
if a.hasPrefix("J") || a.hasPrefix("j") {
if sections[9].sectionName == "J" {
sections[9].words.append(a as String)
}
}
if a.hasPrefix("K") || a.hasPrefix("k") {
if sections[10].sectionName == "K" {
sections[10].words.append(a as String)
}
}
if a.hasPrefix("L") || a.hasPrefix("l") {
if sections[11].sectionName == "L" {
sections[11].words.append(a as String)
}
}
if a.hasPrefix("M") || a.hasPrefix("m") {
if sections[12].sectionName == "M" {
sections[12].words.append(a as String)
}
}
if a.hasPrefix("N") || a.hasPrefix("n") {
if sections[13].sectionName == "N" {
sections[13].words.append(a as String)
}
}
if a.hasPrefix("O") || a.hasPrefix("o") {
if sections[14].sectionName == "O" {
sections[14].words.append(a as String)
}
}
if a.hasPrefix("P") || a.hasPrefix("p") {
if sections[15].sectionName == "P" {
sections[15].words.append(a as String)
}
}
if a.hasPrefix("Q") || a.hasPrefix("q") {
if sections[16].sectionName == "Q" {
sections[16].words.append(a as String)
}
}
if a.hasPrefix("R") || a.hasPrefix("r") {
if sections[17].sectionName == "R" {
sections[17].words.append(a as String)
}
}
if a.hasPrefix("S") || a.hasPrefix("s") {
if sections[18].sectionName == "S" {
sections[18].words.append(a as String)
}
}
if a.hasPrefix("T") || a.hasPrefix("t") {
if sections[19].sectionName == "T" {
sections[19].words.append(a as String)
}
}
if a.hasPrefix("U") || a.hasPrefix("u") {
if sections[20].sectionName == "U" {
sections[20].words.append(a as String)
}
}
if a.hasPrefix("V") || a.hasPrefix("v") {
if sections[21].sectionName == "V" {
sections[21].words.append(a as String)
}
}
if a.hasPrefix("W") || a.hasPrefix("w") {
if sections[22].sectionName == "W" {
sections[22].words.append(a as String)
}
}
if a.hasPrefix("X") || a.hasPrefix("x") {
if sections[23].sectionName == "X" {
sections[23].words.append(a as String)
}
}
if a.hasPrefix("Y") || a.hasPrefix("y") {
if sections[24].sectionName == "Y" {
sections[24].words.append(a as String)
}
}
if a.hasPrefix("Z") || a.hasPrefix("z") {
if sections[25].sectionName == "Z" {
sections[25].words.append(a as String)
}
}
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return sections.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50.0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return arrayForRows.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].sectionName
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// Cellに値を設定する.
cell.textLabel?.font = UIFont.systemFont(ofSize: 20)
cell.textLabel?.textColor = UIColor.black
cell.textLabel!.text = sections[indexPath.section].words[indexPath.row]
return cell
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.beginUpdates()
arrayForRows.remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .automatic)
let userDefaults = UserDefaults.standard
userDefaults.set(arrayForRows, forKey: "data")
tableView.endUpdates()
} 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
}
}
}
words
从另一个控制器,通过这种方式将值添加到Section的数组中;
class InputDataViewController: UIViewController {
// this function is written inside UITextView in this class.
//But I omitted here.
func addData(text: String) {
var data = self.getData()
data.insert(text as NSString, at: 0)
dataDefault.set(data, forKey: "data")
}
func getData() -> [String] {
if let data = dataDefault.stringArray(forKey: "data") {
return data
}
return []
}
}
问题是什么?从我的看法来看,如果我没有明确地写tableView.reloadData()
ortableView.beginUpdates()
和,我可以理解endUpdates()
,但我确实做到了。导致此错误的原因是什么?你可以帮帮我吗?
谢谢。
更新
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return sections[section].words.count
}
另外,我发现如果我这样写,它会起作用。但是,选定的一个没有从我的表格视图中删除。单词的第一个索引已从我的表格视图中删除,无论我选择并删除了一个部分中的一行。删除的行在另一个部分中。
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
// removeHistory(index: sections[indexPath.section].words[indexPath.row])
tableView.beginUpdates()
let indexSet = NSMutableIndexSet()
indexSet.add(indexPath.section)
//let indexSet = sections[indexPath.section].words[indexPath.row] as IndexSet
//sections.remove(at: indexPath.section)
sections[indexPath.section].words.remove(at: indexPath.row)
var data = getData()
data.remove(at: indexPath.row)
dataDefault.set(data, forKey: "data")
dataDefault.synchronize()
//tableView.deleteSections(indexSet, with: UITableViewRowAnimation.fade)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
//
} 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
}
}