UITableview не отвечает при загрузке данных из firebase - PullRequest
0 голосов
/ 08 сентября 2018

My Tableview не реагирует ни на какие касания, когда начинает загружать данные из firebase. (Он уже показывает ячейки, но не реагирует) Через некоторое время выполняется прокрутка, которую вы пытались выполнить, когда табличное представление не реагировало.

var filteredData = [archivCellStruct]()
func firData() {
filteredData.removeAll()
 var databaseRef : DatabaseReference!

    databaseRef = Database.database().reference()

databaseRef.child("Aufträge").child("Archiv").queryOrderedByKey().observe(.childAdded, with:{
        snapshot in
        let snap = snapshot.value as? NSDictionary

        //extracting the data and appending it to an Array
            self.filteredData.append(//myData)
            self.tableView.reloadData()

    })
}

Таким образом, он работает для меньших объемов данных (строк табличного представления), но с большой задержкой (и я уже фильтрую данные, чтобы ограничить данные, отображаемые в табличном представлении). Я думаю, что это как-то связано с tableView.reloadData () (может быть, при перезагрузке отключено взаимодействие с пользователем?)

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

С помощью базы вы можете пойти ручным способом:

UseCase:

struct UseCaseName {
     struct Request {}
     struct Response {
         let firebaseCallbackData: [FirebaseModelType]
     }
     struct ViewModel {
         let data: [DisplayType]
     }
}

ViewController:

var filteredData: [DisplayType]! = []
override func viewWillAppear() {
    // this one can make you trouble, adjust the observation logic to whatever you need. `WillAppear` can fire multiple times during the view lifecycle
    super.viewWillAppear()
    interractor?.observe()
}

func showData(viewModel: Scene.Usecase.ViewModel) {
    // this is where the different approach begins
    tableView.beginUpdates()
    var indexPaths = [NSIndexPath]()
    for row in (filteredData.count..<(FilteredData.count + viewModel.data.count)) {
        indexPaths.append(NSIndexPath(forRow: row, inSection: 0))
    }

    filteredData += viewModel.data

    tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
    tableView.endUpdates()
}

Интеррактор:

func observe(request: Scene.UseCase.Request) { /* signup for updates with observe(_ eventType: DataEventType, with block: @escaping (DataSnapshot) -> Void) -> UInt */
     callback is something like { DataSnapshot in presenter.presentData(response: Scene.Usecase.Response())
}

Presenter:

func presentData(response: Scene.UseCase.Response) {
    /* format for representation */
    DispatchQueue.main.async {
        controller.present(viewModel: Scene.UseCase.ViewModel())
    }
}

Извините за разделение потока, я привык к этому. Также я предполагаю, что данные в базе данных не изменены, но добавлены (из-за части observe(.childAdded,. Если я ошибаюсь, отредактируйте ваш вопрос, чтобы отразить это. Другое предположение, что у вас есть один раздел. Не забудьте поменять inSection: 0 на нужный раздел. Я ленивый и ТАК не так дружелюбен для мобильных устройств Этот способ добавляет только новые значения, отправленные Firebase, и работает быстрее

РЕДАКТИРОВАТЬ: на другой ответ.

DispatchQueue.main.async { //change this in you code self.tableView.reloadData() }

Иногда не рекомендуется перезагружать все предметы. Это зависит от количества однако. Если мои предположения верны, лучше обновить отдельные ячейки, не перезагружая всю таблицу при изменении. Быстрый пример: что-то вроде чата с «бэкендом» Firebase. Объяснение: добавление одной строки будет работать быстрее, чем reloadData () в любом случае, но разница велика только при частом вызове этих методов. В примере с чатом разница может быть достаточно большой, если чат является спамом, чтобы оптимизировать поведение перезагрузки UITableView в вашем контроллере.

Также будет приятно увидеть код, который влияет на методы. Это может быть проблема с потоками, как сказал Джон Айерс в комментариях. Куда вы звоните func firData()?

0 голосов
/ 08 сентября 2018

каждый раз, когда вам нужно асинхронно перезагружать таблицу -

var filteredData = [archivCellStruct]()
func firData() {
filteredData.removeAll()
 var databaseRef : DatabaseReference!

    databaseRef = Database.database().reference()

databaseRef.child("Aufträge").child("Archiv").queryOrderedByKey().observe(.childAdded, with:{
        snapshot in
        let snap = snapshot.value as? NSDictionary

        //extracting the data and appending it to an Array
            self.filteredData.append(//myData)

            DispatchQueue.main.async {      //change this in you code
            self.tableView.reloadData()
            }

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