UITableView 单元格插入失败



我正在尝试制作一个可以具有可扩展标题视图的UITableView。当您按下标题视图中的按钮时,将执行以下函数:

func expandTheCell(_ sender: UIButton) {
self.tableView.beginUpdates()
if sender.isExpanded == false {
postsArray.append("Hello")
tableView.reloadData()
print("Array Count: (postsArray.count)")
self.tableView.insertRows(at: [IndexPath.init(row: 0, section: sender.tag)], with: .fade)
} else {
print("test")
}
self.tableView.endUpdates()
}

以下是一些表视图函数:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        
return postsArray.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}

当我尝试插入行时,出现以下错误:

由于未捕获的异常而终止应用 "NSInternalInconsistencyException",原因:"无效更新:无效 第 1 部分中的行数

为什么我不能插入单元格?我做错了什么?

我认为问题是由于各部分具有相同的dataSource 数组,在您的情况下postsArray,当您在单击按钮时将项目附加到postsArray时,相同的postsArray用于其他部分,因此在section 0中插入行后,section 1抱怨插入操作前后的行数不同, 但是section 0不会抱怨,因为它具有相同的行数和postsArray中的项目数

现在这个问题可以通过两种方式解决:

第一种方法是您也可以为其他部分插入行,然后所有部分的行数与postsArray中的元素数相等

第二种方法是所有部分都有不同的 dataSource 数组,例如第 1 节的postsArray1、第 2 节的postsArray2和其他部分的相同数组。 现在在这种情况下,您不需要为其他部分插入行,因为每个部分都有不同的 dataSource 数组,更改一个不会影响其他部分。

我做了一个简单的项目来演示上述理论:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(buttonTapped(_:)))
self.navigationItem.rightBarButtonItem = addButton
}

var valuesFirstSection = ["value1", "value2", "value3"]
var valuesSecondSection = ["value1Second", "value2Second", "value3Second"]
//if you want to have the same dataSource array then use this
//var sharedValues = ["value1Shared", "value2Shared", "value3Shared"] // shared dataSource array

func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return valuesFirstSection.count
}else {
return valuesSecondSection.count
}
//              //if you want to have the same dataSource array then
//use this
//return sharedValues.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if indexPath.section == 0 {
cell.textLabel?.text = valuesFirstSection[indexPath.row]

}else {
cell.textLabel?.text = valuesSecondSection[indexPath.row]
}
return cell
//if you want to have the same dataSource array then
//use this
//cell.textLabel?.text = sharedValues[indexPath.row]
//return cell
}
func buttonTapped(_ sender: UIBarButtonItem) {

//if you want to have the same dataSource array then
//you need to insert the rows for other sections as well
//                sharedValues.insert("NewValue0", at: 0)
//                self.tableView.insertRows(
//                        at: [IndexPath(row: 0, section: 0),
//                             IndexPath(row: 0, section: 1)
//                        ],
//                        with: .automatic)

valuesFirstSection.insert("NewValue0", at: 0)
self.tableView.insertRows(
at: [IndexPath(row: 0, section: 0)
],
with: .automatic)

}

}

希望这有帮助。

最新更新