iOS: недопустимое обновление: недопустимое количество строк в разделе 0 - PullRequest
0 голосов
/ 03 ноября 2019

Я создаю табличное представление, которое каждый раз при прокрутке до конца таблицы будет отображать мерцание в разделе таблицы 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 является только обновление определенных строк и разделов, поэтому не требуется много времени для обновления таблицы с большим количеством данных ?? Вот и весь мой вопрос, спасибо

1 Ответ

0 голосов
/ 03 ноября 2019

Я просто хочу указать на что-то еще. Вообще говоря, синглтоны - это зло, и я избегаю их как чумы.

Это действительно большой запах кода, и я бы посоветовал вам прекратить использовать этот тип кода:

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

См. Что плохого в синглетах? есть еще много постов в блоге об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...