Home > OS >  pass data from collection view to table view in the same view controller:
pass data from collection view to table view in the same view controller:

Time:12-28

If i click on a particular cell of collection view then the data should be shown related to that cell of collection view in the table view in the same view controller (not in the other view controller)

CodePudding user response:

On didSelectItemAt method of collectionView you reset the data source of tableView and reload tableView that should do the job.

CodePudding user response:

Regardless of having one or multiple view controllers. A good practice is to have a data structure that fits your visual state. For your case I would expect to have something like

var collectionViewItems: [Any]
var tableViewItems: [Any]

But to be more concrete let's assume that we have a collection view of users where after pressing a certain user a table view should update a list of friends for that user.

A data source like the following could show that:

struct User {
    let name: String
    let friends: [User]
}

Now to create a structure that is more fit for your display you could have something like this:

class UserFriendsDataModel {
    let allUsers: [User]
    var selectedUser: User?
    
    init(allUsers: [User]) { self.allUsers = allUsers }
}

In your view controller you would create a new instance of your data model. Probably in viewDidLoad but this all depends on how you collect your data.

For instance

class ViewController: UIViewController {

    private var dataModel: UserFriendsDataModel?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        dataModel = .init(allUsers: [
            .init(name: "Me", friends: [.init(name: "You", friends: [])])
        ])
    }


}

Now your data source implementations can use dataModel?.allUsers for collection view and dataModel?.selectedUser?.friends for your table view.

extension ViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        dataModel?.selectedUser?.friends.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        cell.textLabel?.text = dataModel?.selectedUser?.friends[indexPath.row].name
        return cell
    }
    
}

Now all that is left is interaction. When a collection view cell is pressed you would do

extension ViewController: UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let user = dataModel?.allUsers[indexPath.row]
        dataModel?.selectedUser = user
        tableView?.reloadData()
    }
    
}

note here that a new user is being selected using selectedUser = user and then a reload is triggered for table view calling tableView?.reloadData() which will force the table view to call data source methods and get the new information.

An even better approach may be to listen for changes in selected user by creating your own delegates on your data model and respond to that. But that is already out of scope for this question.

I hope this puts you on the right path.

  • Related