我已经使用类似的UITableViewDiffableDataSource
和NSDiffableDataSourceSnapshot
实现了UITableView
private typealias ListDataSource = UITableViewDiffableDataSource<Section, Wrapper>
private typealias ListSnapshot = NSDiffableDataSourceSnapshot<Section, Wrapper>
enum Wrapper: Hashable {
case one([Company])
case two([Member])
}
private enum Section: CaseIterable {
case main
}
private func configureDataSource() {
dataSource = ListDataSource(tableView: listTableView,
cellProvider: { [weak self] (_, indexPath, wrapper) -> UITableViewCell? in
guard let `self` = self else {
return UITableViewCell()
}
switch wrapper {
case .one(let company):
let cell = self.listTableView.dequeueReusableCell(withIdentifier: "Cell",
for: indexPath)
cell.textLabel?.text = company[indexPath.row].name
return cell
case .two(let member):
let cell = self.listTableView.dequeueReusableCell(withIdentifier: "Cell",
for: indexPath)
cell.textLabel?.text = member[indexPath.row].name.first
return cell
}
})
}
func updateData(_ wrapper: Wrapper) {
var snapshot = ListSnapshot()
snapshot.appendSections([.main])
switch wrapper {
case .one(let comp):
snapshot.appendItems([.one(comp)])
dataSource.apply(snapshot, animatingDifferences: true)
case .two(let member):
snapshot.appendItems([.two(member)])
dataSource.apply(snapshot, animatingDifferences: true)
}
}
关于段更改,更新Wrapper类型的相应数据。但问题是每次只显示一条记录
func handleSegmentChanged(_ sender: UISegmentedControl) {
let member = Member(name: Name(first: "Harshal", last: "Wani"),
memberId: "123", age: 30, email: "harshal@gmail.com", phone: "123456789")
let member2 = Member(name: Name(first: "David", last: "John"),
memberId: "123", age: 30, email: "harshal@gmail.com", phone: "123456789")
let comp = Company(name: "Comp 1", companyId: "", website: "", logo: "", about: "", members: [member, member2])
let comp2 = Company(name: "Comp 2", companyId: "", website: "", logo: "", about: "", members: [member, member2])
if sender.selectedSegmentIndex == 0 {
updateData(.one([comp, comp2]))
} else {
updateData(.two(comp.members))
}
}
感谢您的帮助,谢谢
如果每个部分只应用一个项,则必须声明包装
enum Wrapper: Hashable {
case one(Company)
case two(Member)
}
在handleSegmentChanged
中,创建Wrapper
项的数组,而不是带有关联类型数组的一个Wrapper
。
@IBAction func handleSegmentChanged(_ sender: UISegmentedControl) {
let member = Member(name: Name(first: "Harshal", last: "Wani"), memberId: "123", age: 30, email: "harshal@gmail.com", phone: "123456789")
let member2 = Member(name: Name(first: "David", last: "John"), memberId: "123", age: 30, email: "harshal@gmail.com", phone: "123456789")
let comp = Company(name: "Comp 1", companyId: "", website: "", logo: "", about: "", members: [member, member2])
let comp2 = Company(name: "Comp 2", companyId: "", website: "", logo: "", about: "", members: [member, member2])
if sender.selectedSegmentIndex == 0 {
updateData([.one(comp), .one(comp2)])
} else {
updateData(comp.members.map{.two($0)})
}
}
用代替updateData
func updateData(_ wrapper: [Wrapper]) {
var snapshot = ListSnapshot()
snapshot.appendSections([.main])
snapshot.appendItems(wrapper)
dataSource.apply(snapshot, animatingDifferences: true)
}
configureDataSource
中的[weak self] -> self
舞蹈是无稽之谈。闭包的第一个参数是表视图。使用此实例可避免出现self
,并将configureDataSource
替换为
private func configureDataSource() {
dataSource = ListDataSource(tableView: listTableView,
cellProvider: { (tableView, indexPath, wrapper) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell",
for: indexPath)
switch wrapper {
case .one(let company):
cell.textLabel?.text = company.name
case .two(let member):
cell.textLabel?.text = member.name.first
}
return cell
})
}