Richa Srivastava
Richa Srivastava

Reputation: 21

UITableView reloadRows crashes sometime

I have 4 rows which shows and hide some data below the selected row. Its works fine Most of the time. But when I click second/third/fourth rows multiple times(like 13-14) times and then click on first row then sometime it crashes not always but it crashes most of the time after multiple clicks. I am changing row height as well. Crash only happen when I select first row(case a), after selecting other rows multiple times. Below is my code -

I tried multiple things like calling it between beginUpdate and endUpdate, check is indexPath exist before reloading

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }



 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: ”cell”, for: indexPath) as! CustomTableViewCell

        let model = dataSource[indexPath.row]
        cell.model = model

        switch model.type {
        case .a:
            cell.aList = savedCardList
            cell.addACallback = {[weak self] (sender) in
                self?.moveToAVC()
            }
            cell.addACallback= {[weak self] (a) in
                self?.selectedA = a
                self?.updateButton()
            }

        case .b:
            cell.bList = bList
            cell.bSelectedCallback = {[weak self] (bInfo) in
                self?.selectedB= bInfo
                self?.updateButton()
            }

        case .c:
            cell.cList = cList
            if let cInfo = selectedC {
                cell.selectOtherCButton.setTitle(cInfo.name, for: .normal)
            }
            cell.selectOtherCCallback = {[weak self] (sender) in
                self?.showSelectCVC()
            }
            cell.CSelectedCallback = {[weak self] (cInfo) in
                self?.selectedC = cInfo
                self?.updateButton()
            }

        case .d:
            cell.dTextField.text = dString
            cell.dChangedCallBack = {[weak self] (textField) in
                if let dStr = textField.text {
                    self?.dString = dStr
                }
                self?.updateButton()
            }

        default:
            break
        }
        return cell
    }


 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let model = dataSource[indexPath.row]
        guard model.isSelected == true else {
            return 90
        }
        switch model.type {
        case .a:
            if aList.count > 0 {
                return 350
            }
            return 140

        case .b:
            return 200

        case .c:
            return 270

        case .d:
            return 130

        default:
            return 90
        }
    }


 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let model = dataSource[indexPath.row]
        selectedType = model.type
        updateButtonState(false)
        updateButton()

        if let selectedIndexPath = selectedIndexPath, selectedIndexPath != indexPath {
            self.updatemodelSelectedState(false, at: selectedIndexPath)
            self.updatemodelSelectedState(true, at: indexPath)
            if let _ = tableView.cellForRow(at: indexPath), let _ = tableView.cellForRow(at: selectedIndexPath) {
                self.reloadTableViewRows([selectedIndexPath, indexPath])
                tableView.scrollToRow(at: indexPath, at: .top, animated: true)
            }
        }
        else if !model.isSelected {
            self.updatemodelSelectedState(true, at: indexPath)
                if let _ = tableView.cellForRow(at: indexPath) {
                    self.reloadTableViewRows([indexPath])
                }
        }
        selectedIndexPath = indexPath
    }

 private func reloadTableViewRows(_ indexPaths: [IndexPath]) {
        DispatchQueue.main.async {
            self.myTableView.beginUpdates()
            self.myTableView.reloadRows(at: indexPaths, with: .automatic)
            self.myTableView.endUpdates()
        }
    }

Xcode console log(I am only getting this one liner) -

libc++abi.dylib: terminating with uncaught exception of type NSException

It crashes at self.myTableView.endUpdates() this line. If I remove begin and end updates then it crashes at self.myTableView.reloadRows(at: indexPaths, with: .automatic). Also for one of the row I show a popup on a button click and after then if I select my first row, it crashes!

Also I have collection view inside table view rows which I am hiding and showing. Even though its flow is set to horizontal, after multiple clicks once in a while I notice that collection view rows comes in vertical flow and then in next click it gets back to horizontal flow again. Not sure why this is happening but could this be issue?

Please help. I am trying to resolve this issue from last 2-3 hours :(

Upvotes: -2

Views: 512

Answers (1)

nimesh surani
nimesh surani

Reputation: 177

Try This one i hope it will be work for you:

   UIView.setAnimationsEnabled(false)
   tableView.beginUpdates()
   tableView.reloadRows(at: [indexPath!], with: .none)
   tableView.endUpdates()
   UIView.setAnimationsEnabled(true)

Upvotes: -1

Related Questions