mihai mimi
mihai mimi

Reputation: 133

How to control the contents of a table view based on cell selection in a collection view?

I have a collection view with 4 cells and a table view inside the same view controller. Each cell in the CV must make the table view display a different list; one table cell type per CV cell. When the user taps on one CV cell the table must reload its data and display the correct type of cell, (basically a different list with a custom cell). Each of these lists contains only 1 section.

I created and registered all my different cells with the table view and have all my data ready, with the views set and so on. How do I make the table view discard its current cells (list) and show a new list with different cells when the user has tapped on another CV cell? I suppose that the solution is in the didSelectItem method from the CV delegate but I cannot find any information that shows how to make the table dequeue a different type of cell when the user has changed the cell selection inside the CV; or discard the previous one if needed. At the moment I only register and dequeue one type of cell, and inside the delegate method for the CV I am calling empty functions that are supposed to put the new list inside the table. The number of rows for each list is dynamic and this implies that I would have to call the delegate method on the table view again. I have found an example of the MVVM pattern but I cannot apply it to my logic as that is more static.
Any help would be much appreciated. Thank you.

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let selectedMenuTab = indexPath.item
        switch selectedMenuTab { // show different type of cell.
        case 0: showAList()
        case 1: showBList()
        case 2: showCList()
        case 3: showDList()
        default:
            print("no such main tab")
        }
    }


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableOfConversations.dequeueReusableCell(withIdentifier: rowID, for: indexPath) as! ConversationsListCell
        let messageInChatList = listOfOneToOneChats[indexPath.item]
        cell.messageInChatList = messageInChatList
        cell.selectionStyle = .none
        return cell
    }


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return listOfOneToOneChats.count
    }

Upvotes: 0

Views: 324

Answers (1)

dktaylor
dktaylor

Reputation: 914

I think this should be as simple as calling tableView.reloadData() at the end of the collection view delegate's didSelectItemAt method.

The tableView should have it's data source based on a common array, for example:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return displayingList.count
}

And then in the didSelect of the collection view set that array and then tell the tableView to reload:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let selectedMenuTab = indexPath.item
    switch selectedMenuTab { // show different type of cell.
    case 0: displayingList = listA
    case 1: displayingList = listB
    case 2: displayingList = listC
    case 3: displayingList = listD
    default:
        print("no such main tab")
    }
    tableView.reloadData()
}

And for dequeueing cells, check based on the type if they are different, or based on selectedMenuTab:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UICollectionViewCell
    let selectedMenuTab = indexPath.item
    switch selectedMenuTab { // show different type of cell.
    case 0: cell = tableOfConversations.dequeueReusableCell(withIdentifier: rowID, for: indexPath) as! ConversationsListCell
    //And so on
    default:
        fatalError("No cell for this tab")
    }
    let item = displayingList[indexPath.item]
    // Cell setup
    return cell
}

The type of the values will be something to consider in order to avoid an array of Any, which would not be super type-safe, but that will depend on the types of your objects.

Upvotes: 1

Related Questions