从Firebase加载数据时,UITableview不响应

时间:2018-09-08 19:44:17

标签: ios swift uitableview firebase reload

我的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行),但延迟较大(并且我已经在过滤数据以限制tableView中显示的数据)。 我认为这与tableView.reloadData()有关(也许在重新加载时禁用了用户交互功能?)

2 个答案:

答案 0 :(得分:1)

每次您都必须异步重新加载tableview-

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()
            }

    })
} 

答案 1 :(得分:1)

有了firebase,您可以手动操作:

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())
}

演示者:

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

很抱歉,流程分开了,我沉迷于这种方式。 另外,我假设Firebase中的数据没有被修改,而是被添加了(由于observe(.childAdded,部分。如果我错了,请编辑您的问题以反映这一点。另一个假设是您拥有单个部分。别忘了将inSection: 0更改为适当的部分。我很懒,所以对移动设备不是那么友好 这种方式只会附加Firebase发送的新值,并且运行速度更快

编辑:关于另一个答案。

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

有时重新加载所有项目并不好。但是,这取决于计数。如果我的假设正确,那么最好在不更改时重新加载整个表的情况下更新单独的单元格。快速示例:类似于与Firebase“后端”聊天。说明:添加单行无论如何都要比reloadData()更快,但是仅当您经常调用这些方法时,区别才大。对于聊天示例,如果聊天是垃圾邮件以优化控制器中的UITableView重新加载行为,则差异可能会非常大。

也很高兴看到代码,这会影响方法。就像约翰·艾尔斯(John Ayers)在评论中所说的,这可能是一个线程问题。您在哪里叫func firData()