iOS:无效的更新:第0部分中的行数无效

时间:2019-11-03 13:43:17

标签: ios swift uitableview

我创建一个表格视图,每次我滚动到表格末尾时,它将在表格第1节中显示微光,以等待api加载新数据。 api完成加载数据后,新数据将追加到用于包含在第0部分的表视图中显示的所有数据的数组,然后重新加载表视图以将第1部分的numberOfRowsInSection更新为0以隐藏闪烁并更新该部分0 numberOfRowsInSection

这是我的代码示例

fileprivate var data = [dataArray]() {
        didSet {
            guard !data.isEmpty else {
                return
            }
            tableView.reloadData()
            tableView.layoutIfNeeded()
            view.layoutIfNeeded()
        }
    }

fileprivate var isLoadingMore: Bool = false {
        didSet {
            tableView.reloadSections(IndexSet(integer: 1), with: .automatic)
            tableView.layoutIfNeeded()
            tableViewHeightConstraint.constant = tableView.contentSize.height + 60.0
            view.layoutIfNeeded()
        }
    }

fileprivate func loadData() {
        if let size = self.paging.totalSize,
            data.count >= size {
                return
        }

        let limit = paging.limit
        let offset =  paging.offset

        guard !isLoadingMore else { return }

        isLoadingMore = true
        controller.requestContent(
            completion: { [weak self] (success, offset, size, data) in
                DispatchQueue.main.async {
                    self?.isLoadingMore = false

                    guard let list = data,
                        let data = list as? [dataArray],
                        let size = size else {
                            return
                    }

                    if success {
                        if self?.paging.currentPage == 0 {
                            self?.data = data

                            if self?.scrollView.frame.size.height >= self?.scrollView.contentSize.height {
                                self?.paging.totalSize = size
                                self?.paging.currentPage += 1
                                self?.loadData()
                                return
                            }
                        } else {
                            self?.data.append(contentsOf: songs)
                        }
                        self?.paging.totalSize = size
                        self?.paging.currentPage += 1
                    } else {
                        self?.alert("failed")
                    }
                }
        })
    }

fileprivate func loadDataFromCoreData() {
        isLoadingMore = false

        let context = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
        let dataFromCoreData = Datas.fetchData(context: context).filter({$0.isSaved})

        songs = dataFromCoreData.map({ dataArray(song: $0) })
    }

func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return data.count
        case 1:
            return isLoadingMore ? 1 : 0
        default:
            return 0
        }
    }

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height){
            loadData()
        }
    }

func setupForCeckingAvailableData() {
        utility.checkInternetAccess = { [weak self] result in
            if result {
                self?.paging = Paging()
                self?.loadData()
            } else {
                self?.loadDataFromCoreData()
            }
        }
    }
override func viewDidLoad() {
        super.viewDidLoad()

        setupForCeckingAvailableData()

    }

有时候我第一次加载或尝试通过滚动到表的末尾来获取新数据时,出现崩溃消息是

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

那是什么原因呢?即使每次将新数据追加到变量reloadData()时,即使我已经使用data,也为什么会崩溃。我应该将reloadData()更改为

吗?
tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .automatic)
tableView.endUpdates()

?如果是这样,是因为崩溃导致insertRows仅刷新特定的行和节,所以没有花费大量时间来刷新带有大量数据的表吗? 这就是我的全部问题,谢谢

2 个答案:

答案 0 :(得分:0)

我只想指出一点。 一般来说,单身人士是邪恶的,我像瘟疫一样避免他们。

这是一种真正的大代码味道,建议您停止使用这种类型的代码:

TableView.beginUpdates()
TableView.insertRows(at: indexPaths, with: .automatic)
TableView.endUpdates()

请参见What is so bad about singletons?,还有更多关于此的博客文章。

答案 1 :(得分:0)

经过一些研究,我找到了一个线索。 我在tableView.reloadData()之前添加tableView.reloadSections(IndexSet(integer: 1), with: .automatic),因为当我看到崩溃崩溃发生在tableView.reloadSections(IndexSet(integer: 1), with: .automatic)