UITableViewDiffableDataSource и NSDiffableDataSourceSnapshot для разных объектов показывает только одну строку

Я реализовал UITableView, используяUITableViewDiffableDataSource а также NSDiffableDataSourceSnapshot нравиться

    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))
    }
}

Ценю за любую помощь, спасибо

1 ответ

Решение

Вы применяете только один элемент в разделе, вы должны объявить оболочку

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)
}

В [weak self] -> self танцевать в configureDataSourceерунда. Первый параметр закрытия - это табличный вид. Используйте этот экземпляр, чтобы избежать появления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
    })
}