1

I have a view controller and within the view controller a custom table view and custom table view cells. Within those cells I have a collection view and collection view cells... Essentially, my projects: [Project] = [] within my viewController gets populated with Project objects from Firebase and populates the tableview and tableview cells. I want to grab an array property from these projects and populate the collection view cells within the tableview cells.

The way I am trying to pass the project data into my collection view cells is by using NotificationCenter.default and posting the projects array with a notification. Then, in my ProjectTableViewCell.swift where I configure my collection view and collection view cells, I add another var projects: [Project] = [] which I try to populate using a notification observer and calling a function (populateProjects(notification:)) that grabs the userInfo data from the notification and setting the projects array with the data.

My problem is that the method selector populateProjects(notification:) is not getting called... I set breakpoints and they reach the addObserver method but the selector does not get called. I am also setting the object parameter within the addObserver and post method to nil so any object could receive the notification... I already looked at these posts and replicated what they did but my selector still never gets called. Am I missing something else? Pls help, ty in advance sorry for the long post!!

P.S: I would also appreciate some feedback regarding my approach to nesting a collection view within a table view cells. I looked at many posts that attempted it and this was the method that made the most sense. But mainly I want this notification stuff to work.

stack posts looked at: - NSNotificationCenter addobserver not calling the selector method in SWIFT - NotificationCenter obersever not called in swift 4 - Swift 4 - Notification Center addObserver issue

my ViewController.swift looks like this:

class HomeViewController: UIViewController {

    @IBOutlet weak var homeTableView: UITableView!

    var projects: [Project] = []
    var db: Firestore!
    let nc = NotificationCenter.default
    let projectsNotification = Notification.Name(rawValue: "projectsDataNotification")

    override func viewDidLoad() {
        super.viewDidLoad()

        homeTableView.delegate = self
        homeTableView.dataSource = self
        homeTableView.separatorStyle = .none

        db = Firestore.firestore()

        db.collection("projects").getDocuments { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    let project = Project(id: document.documentID, documentData: document.data())!
                    print(document.data())
                    self.projects.append(project)
                }
                self.homeTableView.reloadData()
            }
        }
        nc.post(name: projectsNotification, object: nil, userInfo: ["projects": projects])
        homeTableView.reloadData()
    }
}

my ProjectTableViewCell.swift looks like this:

class ProjectTableViewCell: UITableViewCell {
    @IBOutlet private weak var collectionView: UICollectionView!

    var projects: [Project] = []
    let nc = NotificationCenter.default
    let projectsNotification = Notification.Name(rawValue: "projectsDataNotification")

    override func awakeFromNib() {
        super.awakeFromNib()
        collectionView.dataSource = self
        collectionView.delegate = self

        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumLineSpacing = 10.0
        flowLayout.minimumInteritemSpacing = 10.0
        collectionView.collectionViewLayout = flowLayout

        nc.addObserver(self, selector: #selector(self.populateProjects), name: projectsNotification, object: nil)
    }

    @objc func populateProjects(notification: Notification) {
        let userInfo: [String: Any] = notification.userInfo as! [String : Any]
        let projectsData = userInfo["projects"] as! [Project]
        self.projects = projectsData

        for project in projectsData {
            print("TEST projectsData TableCell: \(project.title)")
        }
    }
}

extension ProjectTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return projects[section].needs.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "needsCell", for: indexPath)

        let cellLayer = cell.layer
        cellLayer.borderWidth = 0.75
        cellLayer.cornerRadius = 6

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 75, height: 30)
    }  
}
gflo
  • 186
  • 3
  • 13
  • 1
    Wrong order: Firstly you posted notification and only then subscribed to it. PS You really should consider use something else to manage data transfer, Notification Center is most poorly choice IMO – Sergey Gamayunov Sep 21 '19 at 18:14
  • 1
    Also (though this is not the cause of the problem) defining the `projectsNotification` in two different places completely defeats the purpose of Notification.Name. – matt Sep 21 '19 at 18:16
  • 1
    Sergey, what would be the appropriate way to pass the data from the table view cell to the collection view cell? Every tutorial I found with nested collection view in table view only used dummy fake data so I had to improvise the best way I could which was Notification Center :/ – gflo Sep 21 '19 at 20:04
  • 1
    It looks like you're posting the notification outside of the asynchronous `getDocuments` call, so it will fire before you have any projects. [This tutorial](https://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell-in-swift/) will help you accomplish your goal. – Don Sep 21 '19 at 21:00

0 Answers0