首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元格不使用UITableVIewDiffableDataSource加载

单元格不使用UITableVIewDiffableDataSource加载
EN

Stack Overflow用户
提问于 2020-02-22 09:24:15
回答 1查看 981关注 0票数 2

我试图用新的DiffableDataSource api实现表视图,但是单元格根本不加载:

代码语言:javascript
复制
var tableView = UITableView()
    var currencyPairsArray = [String]()
    lazy var fetcher = NetworkDataFetcher()

    lazy var searchText = String()
    lazy var searchArray = [String]()
    lazy var searchController: UISearchController = {
        let controller = UISearchController(searchResultsController: nil)
        controller.hidesNavigationBarDuringPresentation = false
        controller.obscuresBackgroundDuringPresentation = false
        controller.searchBar.delegate = self
        return controller
    }()

    fileprivate var dataSource : UITableViewDiffableDataSource<Section, String>!

    var searchBarIsEmpty: Bool {
        return searchController.searchBar.text?.isEmpty ?? true
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        setupVC()
        setupTableView()
        setupDataSource()
        performSearch(with: nil)


        fetcher.fetchCurrencyPairs { [weak self] pairsArray in
            self?.currencyPairsArray.append(contentsOf: pairsArray)
            DispatchQueue.main.async {
                self?.tableView.reloadData()
            }
        }
        //tableView.reloadData()

        // Do any additional setup after loading the view.
    }

    func setupVC() {
        view.backgroundColor = .white
        view.addSubview(tableView)
        navigationItem.title = "Currency pairs"
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false

    }

    func setupTableView() {
        tableView.delegate = self
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.pinToSuperView()
        tableView.register(UINib(nibName: "CurrencyPairCell", bundle: nil), forCellReuseIdentifier: CurrencyPairCell.reuseIdentifier)
    }


    func setupDataSource() {
        dataSource = UITableViewDiffableDataSource<Section, String>(tableView: tableView, cellProvider: { [weak self] (tableView, indexPath, _) ->  UITableViewCell?  in
            let cell = tableView.dequeueReusableCell(withIdentifier: CurrencyPairCell.reuseIdentifier, for: indexPath) as! CurrencyPairCell
            cell.delegate = self
            let pair = self?.currencyPairsArray[indexPath.row].formattedPair()
            cell.currencyPairLabel.text = pair
            cell.currencyPair = self?.currencyPairsArray[indexPath.row] ?? ""
            return cell
        })
    }

    func performSearch(with filter: String?) {

        var snapshot = NSDiffableDataSourceSnapshot<Section, String>()

        if let filter = filter {
            let filteredPairs = currencyPairsArray.filter {$0.contains(filter)}

            snapshot.appendSections([.main])
            snapshot.appendItems(filteredPairs, toSection: .main)
            dataSource.apply(snapshot, animatingDifferences: true)
        } else {
            let pairs = currencyPairsArray.sorted()
            snapshot.appendSections([.main])
            snapshot.appendItems(pairs, toSection: .main)
            dataSource.apply(snapshot)
        }

    }

}

extension CurrencyListViewController: UISearchBarDelegate {

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

        performSearch(with: searchText)
    }

}

extension CurrencyListViewController {
    fileprivate enum Section: Hashable {
        case main
    }
}

此外,我还收到了xcode的警告:

TableView只警告一次: UITableView被告知在不处于视图层次结构的情况下布局其可见的单元格和其他内容(表视图或其超级视图之一尚未添加到窗口中)。这可能会导致错误,因为强制表视图中的视图加载和执行布局而没有精确的信息(例如表视图边界、特征收集、布局边距、安全区域嵌入等),并且还会由于额外的布局传递而造成不必要的性能开销。在UITableViewAlertForLayoutOutsideViewHierarchy上设置一个符号断点,以便在调试器中捕捉到这一点,并查看导致这种情况发生的原因,这样,如果可能的话,您可以完全避免此操作,或者将其推迟到将表视图添加到窗口之后。表视图:;layer =;contentOffset:{0,0};contentSize:{414,0};adjustedContentInset:{0,0,0};dataSource: dataSource 0x600002960ca0>>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-22 10:12:39

首先,代码中存在一个很大的设计错误。

使用UITableViewDiffableDataSource,停止在索引路径和数据源数组中进行思考。相反,在数据源中考虑

setupDataSource中,您总是从数据源数组currencyPairsArray获得行的模型项,而不管您是否要显示筛选过的数据。忘记currencyPairsArray和索引路径。利用闭包中的第三个参数,它表示

代码语言:javascript
复制
func setupDataSource() {
    dataSource = UITableViewDiffableDataSource<Section, String>(tableView: tableView, cellProvider: { [weak self] (tableView, _, pair) ->  UITableViewCell?  in
        let cell = tableView.dequeueReusableCell(withIdentifier: CurrencyPairCell.reuseIdentifier, for: indexPath) as! CurrencyPairCell
        cell.delegate = self
        cell.currencyPairLabel.text = pair.formattedPair()
        cell.currencyPair = pair
        return cell
    })
}

若要消除警告,请执行第一次重新加载数据,而不使用动画。向performSearch添加一个布尔参数。与其检查nil,不如检查空字符串

代码语言:javascript
复制
func performSearch(with filter: String, animatingDifferences: Bool = true) {

    var snapshot = NSDiffableDataSourceSnapshot<Section, String>()

    let pairs : [String]
    if filter.isEmpty {
        pairs = currencyPairsArray.sorted()
    } else {
        pairs = currencyPairsArray.filter {$0.contains(filter)}           
    }
    snapshot.appendSections([.main])
    snapshot.appendItems(pairs, toSection: .main)
    dataSource.apply(snapshot, animatingDifferences: animatingDifferences)

}

当使用时,从不调用tableView.reloadData(),这很可能是引发问题的原因。

替换

代码语言:javascript
复制
    performSearch(with: nil)


    fetcher.fetchCurrencyPairs { [weak self] pairsArray in
        self?.currencyPairsArray.append(contentsOf: pairsArray)
        DispatchQueue.main.async {
            self?.tableView.reloadData()
        }
    }

使用

代码语言:javascript
复制
    fetcher.fetchCurrencyPairs { [weak self] pairsArray in
        self?.currencyPairsArray.append(contentsOf: pairsArray)
        DispatchQueue.main.async {
            self?.performSearch(with: "", animatingDifferences: false)
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60350719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档