'Invalid update: invalid number of rows in section 1

混江龙づ霸主 提交于 2020-02-24 14:46:06

问题


I am trying to reorder the chats in a tableView. The most recent updated chat should be insert at IndexPath(row: 0, section: 1). My understanding is that in order to delete a row, it must be visible.

If the row is not visible, when Data Source is updated, I just have to tableView.insertRows(at: [newIndex], with: .fade).

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (17) must be equal to the number of rows contained in that section before the update (17), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

//chats of the currentUser
var currentUserChats = [Chat]() {
    didSet(newValue){
       attachChildChangedObserverOn(chat: newValue)
    }
}

var observersArray = [String: UInt]() // chatUID: handle


//attach childChange listener on each chat downloaded
func attachChildChangedObserverOn(chat: Chat) {


    var handle: UInt = 0
    let ref =   DDatabaseRReference.chats.reference().child(chat.chatUID).child("users").child(currentUser.userUID)


    handle = ref.observe(.childChanged, with: {[weak self] (snapshot) in

        self?.observersArray[chat.chatUID] = handle

        guard snapshot.exists() else {return}

        let chatChanged = chat

        var lastMessage = ""
        var unreadMessagesCount = 0
        var lastUpdate = 0.0

        switch snapshot.key {

        case "lastMessage" :
           lastMessage = snapshot.value as! String
            chatChanged.lastMessage = lastMessage

        case "unreadMessagesCount":
             unreadMessagesCount = snapshot.value as! Int
             if let index = chatChanged.users.index(of: (self?.currentUser)!) {
                let userChanged = chatChanged.users[index]
                userChanged.unreadMessagesCount = unreadMessagesCount

                chatChanged.users.remove(at: index)
                chatChanged.users.insert(userChanged, at: index)
             }

        case "lastUpdate":
            lastUpdate = snapshot.value as! Double
            chatChanged.lastUpdate = lastUpdate

        default: return
        }


        let newIndex = IndexPath(row: 0, section: 1)

         // get indexOf chatChanged
    guard let index = self?.currentUserChats.index(of: chatChanged) else {return}
          let indexPathOfOldChat = IndexPath(row: index, section: 1)

          // - update Data Source
          // - reloadRow
        if indexPathOfOldChat.row == 0 {
            self?.currentUserChats.remove(at: 0)
            self?.currentUserChats.insert(chatChanged, at: 0)
            self?.tableView.reloadRows(at: [newIndex], with: .fade)
            return
        }


        //get visible indexes of cells in TableView
        let visibleIndexes = self?.tableView.indexPathsForVisibleRows

         //check if the index of chat to be updated is visible
        if let indexes = visibleIndexes,
                   indexes.contains(indexPathOfOldChat) {

            //index is visible
           // update Data Source, delete row & insert row
            self?.tableView.beginUpdates()
            self?.currentUserChats.remove(at: indexPathOfOldChat.row)
            self?.tableView.deleteRows(at: [indexPathOfOldChat], with: .fade)

            self?.currentUserChats.insert(chatChanged, at: 0)
            self?.tableView.insertRows(at: [newIndex], with: .fade)
            self?.tableView.endUpdates()
            return
        }

        //if index is not visible:
        // - update Data Source
        // - insert the row
        self?.currentUserChats.remove(at: index)
        self?.currentUserChats.insert(chatChanged, at: 0)

        self?.tableView.beginUpdates()
        self?.tableView.insertRows(at: [newIndex], with: .fade)
        self?.tableView.endUpdates()
        return
    })
}

回答1:


It turns out that rows that are not visible can be deleted.
Initially, I had thought that I would get an error if I tried to delete a row that was not visible because that cell for that row would no longer be in the view.

   //if index is not visible:
    // - update Data Source
    // - DELETE the previous row
    // - insert the new row

        self?.currentUserChats.remove(at: indexRow)
        self?.currentUserChats.insert(chatChanged, at: 0)

        self?.tableView.beginUpdates()
        self?.tableView.deleteRows(at: [indexPathOfOldChat], with: .none)
        self?.tableView.insertRows(at: [newIndex], with: .fade)
        self?.tableView.endUpdates()
        return


来源:https://stackoverflow.com/questions/53061782/invalid-update-invalid-number-of-rows-in-section-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!