You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用UITableViewDiffableDataSource展示不同对象时仅显示一行的问题求助

Hey there! The issue you're facing is because right now, you're treating an entire array of Company or Member as a single item in your diffable snapshot. That's why only one row shows up—your data source thinks there's just one item to display, even though that item contains multiple entries.

Let's fix this step by step:

1. Adjust the Wrapper enum to represent individual items

Right now, Wrapper wraps an array of objects. We need to change it to wrap a single object instead, so each row in the table corresponds to one Wrapper instance:

enum Wrapper: Hashable {
    case one(Company) // Now wraps a single Company, not an array
    case two(Member)  // Now wraps a single Member, not an array
}

2. Update the data source's cell provider logic

Since each Wrapper now holds a single item, you don't need to use indexPath.row to access elements from an array. You can directly use the wrapped object:

private func configureDataSource() {
    dataSource = ListDataSource(tableView: listTableView, cellProvider: { [weak self] (_, indexPath, wrapper) -> UITableViewCell? in
        guard let self = self else { return UITableViewCell() }
        let cell = self.listTableView.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
    })
}

3. Rewrite the updateData method to add individual items to the snapshot

Instead of adding one wrapper that contains an entire array, we'll convert each object in your array to a Wrapper and add all of them to the snapshot:

func updateData(with items: [Wrapper]) {
    var snapshot = ListSnapshot()
    snapshot.appendSections([.main])
    snapshot.appendItems(items)
    dataSource.apply(snapshot, animatingDifferences: true)
}

4. Update the segment control handler to pass individual items

Modify handleSegmentChanged to map your arrays into arrays of Wrapper instances and pass them to updateData:

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 {
        // Convert each Company to a Wrapper.one instance
        let companyItems = [comp, comp2].map { Wrapper.one($0) }
        updateData(with: companyItems)
    } else {
        // Convert each Member to a Wrapper.two instance
        let memberItems = comp.members.map { Wrapper.two($0) }
        updateData(with: memberItems)
    }
}

That's it! Now when you switch segments, the table view will display one row for each Company or Member in your arrays, instead of a single row containing the whole array.

内容的提问来源于stack exchange,提问作者Harshal Wani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 15:27:35