UITableView 单元格插入失败

Posted

技术标签:

【中文标题】UITableView 单元格插入失败【英文标题】:UITableView cell insertion failure 【发布时间】:2017-09-16 01:44:38 【问题描述】:

我正在尝试制作一个具有可扩展标题视图的 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 节中的行数

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

【问题讨论】:

尝试删除tableView.reloadData()然后运行程序 删除了,还是不行 现在也评论postsArray.append("Hello") 并简单地插入一行,它是否也会给出错误? 是的,即使我删除了它仍然会给出错误 你能显示numberOfSections方法的代码吗? 【参考方案1】:

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

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

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

第二种方法是所有部分都有不同的数据源数组,例如第 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)


        




希望这会有所帮助。

【讨论】:

是的,这行得通。现在在我的应用程序中的问题是我将无法为所有部分预定义数组,因为部分的数量取决于用户。即使我不知道部分的数量,有没有办法让它仍然工作? @Mr.Man “段数取决于用户”,请多解释 这个表格视图应该是供用户查看其他人的帖子的。例如,如果 User1 没有关注很多人,他们可能只有 1 个部分。如果 User2 确实关注了很多人,他们可能有 50 个部分。 @Mr.Man 这取决于您如何为用户获取数据,假设您为 user1 获得了两个帖子数组,这意味着 user1 将有 2 个部分,对吧?由于这与您原来的问题不同,您应该提出一个新问题并提供相关信息,以便其他人也可以帮助您 好的,假设我对后端进行了 GET 调用,它将返回用户的帖子数。假设这个数字是 5。我将如何创建 5 个新数组放入 numberOfRowsInSection

以上是关于UITableView 单元格插入失败的主要内容,如果未能解决你的问题,请参考以下文章

IOS UITableView检查一个单元格

UITableview:无法从其数据源获取单元格

如何在自定义单元格的 initWithStyle: 方法中获取 UITableView 的宽高?

UITableView - 通过点击现有单元格插入新行

带有自定义单元格的 UITableView 弹出窗口失败,单元格属性始终为零

在uitableview中间插入单元格