Таким образом, этот API все еще находится на стадии бета-тестирования, что означает, что документация не завершена.
В нем говорится:
Эта документация содержит предварительную информацию об API или технологии в разработке.Эта информация может быть изменена, и программное обеспечение, реализованное в соответствии с этой документацией, должно быть протестировано с окончательным программным обеспечением операционной системы.
TLDR - На данный момент, если вы создаете UITableView
и используетеUITableViewDiffableDataSource
, который возвращает ноль, ваше приложение будет аварийно завершено.
Тем не менее, этот пост в блоге содержит некоторые новые подробности.Это не упоминает ничего о возврате ноля для клетки, хотя.
Вы также можете взглянуть на этот сеанс WWDC.Примерно через 15 минут вы увидите, что пример кода выдает фатальную ошибку, если ячейка не может быть создана.
Используя блог выше, я сделал простой tableView в Xcode 11 следующим образом:
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)
}
}
Все отлично загружается, поэтому я решил посмотреть, что произойдет, если я верну nil для ячейки,Я добавил этот код в UITableViewDiffableDataSource
:
if contact.name == "Bob" {
return nil
}
Это закончилось тем, что вызвало сбой:
*** 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>'
На самом деле просто возвращение nil (без ячейки вообще) также вызывает сбой каккак только источник данных применяет обновление.Так что на данный момент, насколько я могу судить, возврат nil не является реальным вариантом, так как он вызывает сбой.
Вы можете оформить полный проект на github.