尝试使同一索引路径的多个单元出队,这是不允许的Swift

时间:2019-05-27 07:59:01

标签: ios swift uitableview

在我的应用中,我有一个TabBar导航系统。当应用为第一个选项卡加载视图控制器时,其中的calendarTableView会正常加载,但是如果我切换到另一个选项卡然后返回到第一个选项卡,则会出现NSInternalInconsistencyException Attempted to dequeue multiple cells for the same index path错误。将单元格声明为let cell = tableView.dequeueReusableCell(withIdentifier: "calendarCell", for: indexPath) as! CalendarTableViewCell会给我错误。目前,我按照其他帖子中的建议解决了该问题,方法是未在cellForRowAt方法的单元格声明中指定indexPath并将其声明为:let cell = tableView.dequeueReusableCell(withIdentifier: "calendarCell") as! CalendarTableViewCell,但这意味着我在错误地管理数据源或出现该错误的原因是什么?是否不应该总是指定indexPath?我进行了一次测试,因为直到现在我还没有遇到问题,并且我将系统日期更改为较早的日期,例如每月的10号,但我没有收到错误消息。因此,这是否意味着tableview试图使太多单元出队?你知道发生了什么吗?我真的很感谢对此的一些解释。 一如既往,非常感谢您的宝贵时间。 这是我正在使用的代码:

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

        let cell = tableView.dequeueReusableCell(withIdentifier: "calendarCell", for: indexPath) as! CalendarTableViewCell
//        let cell = tableView.dequeueReusableCell(withIdentifier: "calendarCell") as! CalendarTableViewCell
        cell.configureUi()
        let date = datesArray[indexPath.row]
        cell.cellDate = String( describing: date)
        let calendar = Calendar.current
        let components = calendar.dateComponents([.year, .month, .day, .weekday], from: date)
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "EEEE"
        let dayInWeek = dateFormatter.string(from: date)
//        cell.dayLabel.text = "\(String(describing: components.day!))" + " " + "\(dayNamesArray[components.weekday! - 1])"
        cell.dayLabel.text = "\(String(describing: components.day!))" + " " + dayInWeek
        cell.cellWeekday = components.weekday!
        //        print("cell weekday is: \(cell.cellWeekday!)") // prints correct weekday
        cell.cellId = "\(String(format:"%04d", components.year!))" + "\(String(format:"%02d", components.month!))" + "\(String(format:"%02d", components.day!))"
        self.selectedDate = cell.cellId // used for time slots cellId
        //        print("##################### selectedDate in tableview is :\(self.selectedDate) ")
        // highlighting current day cell
        if indexPath.row == self.actualDay - 1 && self.actualMonth == self.displayedMonth {
            cell.layer.borderWidth = 4
            if Theme.selectedTheme == 1 {
                if #available(iOS 11.0, *) {
                    cell.layer.borderColor = Theme.calendarCellToday?.cgColor
                } else {
                    // Fallback on earlier versions
                    cell.layer.borderColor = Theme.calendarCellTodayRgb.cgColor
                }

            } else if Theme.selectedTheme == 2 {
                if #available(iOS 11.0, *) {
                    cell.layer.borderColor = Theme.calendarCellToday2?.cgColor
                } else {
                    // Fallback on earlier versions
                    cell.layer.borderColor = Theme.calendarCellTodayRgb2.cgColor
                }
            }
            //            print(" @@@@@@@@@@@@@@@@@@@@@@@@@@   selected cell weekday is: \(cell.cellWeekday!) @@@@@@@@@@@@@@@@@@@@ ")
            self.selectedDate = cell.cellId
        }
        return cell
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? CalendarTableViewCell {
            cell.configureUi()
            // highlighting current day cell
            if indexPath.row == self.actualDay - 1 && self.actualMonth == self.displayedMonth {
                cell.layer.borderWidth = 4
                if Theme.selectedTheme == 1 {
                    if #available(iOS 11.0, *) {
                        cell.layer.borderColor = Theme.calendarCellToday?.cgColor
                    } else {
                        // Fallback on earlier versions
                        cell.layer.borderColor = Theme.calendarCellTodayRgb.cgColor
                    }
                } else if Theme.selectedTheme == 2 {
                    if #available(iOS 11.0, *) {
                        cell.layer.borderColor = Theme.calendarCellToday2?.cgColor
                    } else {
                        // Fallback on earlier versions
                        cell.layer.borderColor = Theme.calendarCellTodayRgb2.cgColor
                    }
                }
                //            print(" @@@@@@@@@@@@@@@@@@@@@@@@@@   selected cell weekday is: \(cell.cellWeekday!) @@@@@@@@@@@@@@@@@@@@ ")

                self.selectedDate = cell.cellId
            }
        }
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? CalendarTableViewCell {
            cell.layer.borderWidth = 4
            if Theme.selectedTheme == 1 {
                if #available(iOS 11.0, *) {
                    cell.layer.borderColor = Theme.firstTintColor?.cgColor
                } else {
                    // Fallback on earlier versions
                    cell.layer.borderColor = Theme.firstTintColorRgb.cgColor
                }

            } else if Theme.selectedTheme == 2 {
                if #available(iOS 11.0, *) {

                    cell.layer.borderColor = Theme.firstTintColor2?.cgColor
                } else {
                    // Fallback on earlier versions
                    cell.layer.borderColor = Theme.firstTintColorRgb2.cgColor
                }
            }
            self.updateTimeSlots(selectedCell: cell)
        }
    }

    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        let cell: CalendarTableViewCell = tableView(self.calendarTableview, cellForRowAt: IndexPath.init(row: self.actualDay - 1, section: 0)) as! CalendarTableViewCell
        self.updateTimeSlots(selectedCell: cell)

    }

1 个答案:

答案 0 :(得分:1)

实际原因很可能在scrollViewDidEndScrollingAnimation中。

永远不会自己调用数据源方法tableView(_:cellForRowAt:)(与cellForRow(at:不同)。它是由框架专门调用的。

强烈不建议您操纵cellForRow之外的单元格。修改模型并重新加载行。