首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么将零tableViewCell返回给UITableViewDiffableDataSource cellProvider param?

为什么将零tableViewCell返回给UITableViewDiffableDataSource cellProvider param?
EN

Stack Overflow用户
提问于 2019-06-11 11:45:42
回答 1查看 1.3K关注 0票数 2

iOS 13有一些处理tableView的新API,其中一个有趣的领域是cell provider 参数 of UITableViewDiffableDataSource

代码语言:javascript
复制
public typealias CellProvider = (UITableView, IndexPath, ItemIdentifierType) -> UITableViewCell?

何时在这里返回a nil UITableViewCell是合适的?

EN

回答 1

Stack Overflow用户

发布于 2019-06-11 13:17:53

所以这个API仍然处于测试版,这意味着文档还没有完成。

它指出:

本文档包含关于正在开发的API或技术的初步信息。这些信息可能会发生变化,根据这些文档实现的软件应该使用最终的操作系统软件进行测试。

TLDR--从现在开始,如果您创建一个UITableView UITableViewDiffableDataSource 并使用返回为零的,则应用程序将崩溃。

然而,博客文章介绍了一些新的细节。但它并没有提到回零换手机的事。

您还可以查看 WWDC会话。在15分钟的标记附近,您可以看到,如果无法创建单元格,示例代码将抛出致命错误。

使用上面的博客,我在Xcode 11中制作了一个简单的tableView,如下所示

代码语言:javascript
复制
class ViewController: UIViewController {

    enum Section: CaseIterable {
        case friends
        case family
        case coworkers
    }

    struct Contact: Hashable {
        var name: String
        var email: String
    }

    struct ContactList {
        var friends: [Contact]
        var family: [Contact]
        var coworkers: [Contact]
    }

    private let tableView = UITableView()
    private let cellReuseIdentifier = "cell"
    private lazy var dataSource = makeDataSource()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UITableViewCell.self,
                           forCellReuseIdentifier: cellReuseIdentifier
        )

        tableView.dataSource = dataSource

        view.addSubview(tableView)

        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        loadData()
    }


    func makeDataSource() -> UITableViewDiffableDataSource<Section, Contact> {
        let reuseIdentifier = cellReuseIdentifier

        return UITableViewDiffableDataSource(
            tableView: tableView,
            cellProvider: {  tableView, indexPath, contact in
                let cell = tableView.dequeueReusableCell(
                    withIdentifier: reuseIdentifier,
                    for: indexPath
                )

                cell.textLabel?.text = contact.name
                cell.detailTextLabel?.text = contact.email
                return cell
            }
        )
    }

    func update(with list: ContactList, animate: Bool = true) {
        let snapshot = NSDiffableDataSourceSnapshot<Section, Contact>()
        snapshot.appendSections(Section.allCases)

        snapshot.appendItems(list.friends, toSection: .friends)
        snapshot.appendItems(list.family, toSection: .family)
        snapshot.appendItems(list.coworkers, toSection: .coworkers)

        dataSource.apply(snapshot, animatingDifferences: animate)
    }

    func loadData() {
        let friends = [
            Contact(name: "Bob", email: "Bob@gmail.com"),
            Contact(name: "Tom", email: "Tom@myspace.com")
        ]

        let family = [
            Contact(name: "Mom", email: "mom@aol.com"),
            Contact(name: "Dad", email: "dad@aol.com")
        ]

        let coworkers = [
            Contact(name: "Mason", email: "tim@something.com"),
            Contact(name: "Tim", email: "mason@something.com")
        ]

        let contactList = ContactList(friends: friends, family: family, coworkers: coworkers)
        update(with: contactList, animate: true)
    }
}

所有的负载都很好,所以我决定看看如果我返回一个单元格时会发生什么,所以我在UITableViewDiffableDataSource中添加了下面的代码

代码语言:javascript
复制
if contact.name == "Bob" {
    return nil
}

这最终导致了一场坠机:

代码语言:javascript
复制
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource returned a nil cell for row at index path: <NSIndexPath: 0xd6d99b18b93a5a0e> {length = 2, path = 0 - 0}. Table view: <UITableView: 0x7f8d30006200; frame = (-207 -448; 414 896); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60000239de00>; layer = <CALayer: 0x600002dd0ec0>; contentOffset: {0, 0}; contentSize: {414, 264}; adjustedContentInset: {0, 0, 0, 0}; dataSource: <_TtGC5UIKit29UITableViewDiffableDataSourceOC5iOS1314ViewController7SectionVS2_7Contact_: 0x600002ffc520>>, dataSource: <_TtGC5UIKit29UITableViewDiffableDataSourceOC5iOS1314ViewController7SectionVS2_7Contact_: 0x600002ffc520>' 

事实上,只要返回零(根本没有单元格),一旦数据源应用更新,也会导致崩溃。因此,目前为止,据我所知,返回零并不是一个真正的选择,因为它会导致崩溃。

您可以在github上签出全工程

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56542970

复制
相关文章

相似问题

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