繁体   English   中英

从UIDocument获取单元格数据时,如何确保UITableView中显示的列表顺序

[英]How to ensure the order of list shown in UITableView when getting data for cell from UIDocument

我的应用程序通过FileManager为UITableView中的每个单元获取数据。 单元格需要来自需要打开UIDocument对象的文件中的数据。 但是,似乎打开完成处理程序中的代码无法预料地执行,因此单元格不会按我希望的顺序显示。

我该如何解决这个问题? 如果有人提供任何线索,我将不胜感激。

override func viewWillAppear(_ animated: Bool) {
   super.viewWillAppear(true)
   fetchCellsData()
}

func fetchCellsData() {

    do {
        let files = getUrlsOfFiles()    //files in a certain order
        for file in files {

            let document = MyDocument(fileURL: file) //MyDocument subclassing UIDocument

            //open to get data for cell
            document.open { (success) in
                if !success {
                    print("File not open at %@", file)
                    return
                }

                let data = populateCellData(document.fileInfo)

                self.cellsData.append(data)
                self.tableView.reloadData()

                /// tried below also
                //  DispatchQueue.main.async {
                //    self.cellsData.append(data)
                //    self.tableView.reloadData()
                //  }
            }
            document.close(completionHandler: nil)
        }

    } catch {
        print(error)
    }
}

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

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyCell
    let fileInfo = cellsData[indexPath.row].fileInfo
    //assign fileInfo into MyCell property
    return cell
}

我预计单元格将按照“文件”的顺序进行渲染,但是,假设顺序是有点不可预测的,因为这是由于在知道完整的“ cellsData”集之前调用了“ cellForRowAt”这一事实。

摘自UIdocument上的Apple文档。 苹果文档

打开(completionHandler :)

异步打开文档。

这意味着,即使您以正确的顺序触发document.open ,也无法保证completionHandler序列的顺序相同,这就是为什么该顺序不可预测的原因

但是,您知道他们最终将全部完成。

您可以做的是:

1-将打开的文档中的所有数据放入另一个列表

2-根据您的需要order此清单

3-将此列表放入cellsData (我假设已绑定到您的tableViesDatasource)


var allDatas: [/*your data type*/] = []

...

    do {
        // reset allDatas 
        allDatas = []
        let files = getUrlsOfFiles()

        for file in files {

            let document = MyDocument(fileURL: file) 
            document.open { (success) in
                if !success {
                    print("File not open at %@", file)
                    return
                }

                let data = populateCellData(document.fileInfo)

                self.allDatas.append(data) // "buffer" list
                self.tableView.reloadData()  
            }
            document.close(completionHandler: nil)
        }

    } catch { ... 

然后,将cellsData更改为如下所示的计算属性:

var cellsData: [/*your data type*/] {
   get {
      return allDatas.order( /* order in accordance to your needs */ )
   }
}

这样,每次添加新数据时,列表都是排序器,然后重新显示。


讨论区

这是关于代码状态的更简单的解决方案,但是,这可能不是整体的首选解决方案。 例如,在您的代码中,您每次添加新值都会重新加载tableview,因为您知道之后会添加更多数据,而这些数据并未进行优化。

我建议您阅读Dispatch Group ,这是一种在执行某些操作之前等待触发的所有异步操作完成(例如在这种情况下重新加载表格视图 )的一种方法(阅读: Raywenderlich tuts

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM