Search code examples
swiftdelegatesprotocols

Protocol Method not being called


Please assist. What I'm trying to achieve is that when I tap on a specific collectionViewCell the ReportDetailsMapController is pushed and my reports[indexPath.item] is sent from MainController to the ReportDetailsMapController.

PROTOCOL:

 protocol MainControllerDelegate: class {
     func sendReport(data: ReportModel)
 }

FIRST VC:

 class MainController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    var delegate: MainControllerDelegate?


    override func viewDidLoad() {
        super.viewDidLoad()
    }
     
      
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
       let report = reports[indexPath.item]
       //When I print(report.name) here. Everything executes correctly 
     
       self.delegate?.sendReport(data: report)

       self.navigationController?.pushViewController(ReportDetailsMapController(), animated: true)
    }
     

 }

SecondVC:

 class ReportDetailsMapController: UIViewController, MainControllerDelegate  {
     
    override func viewDidLoad() {
       super.viewDidLoad()
    
       let mc = MainController()
       mc.delegate = self

     }
      
     func sendReport(data: ReportModel) {

       print(data.name)//This does not execute when ReportDetailsMapController is loaded.
       print("Report sent")

     }


 }

ReportModel:

 class ReportModel: NSObject {   
      var name: String?
      var surname: String?
      var cellNumber: String?
 }   

Solution

  • That method is not called because you didn't assign the view controller you're pushing to the delegate property.
    When the cell is selected, you could do in this order: initialize the view controller and assign it to the delegate, then call the delegate method and push that view controller:

        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
           let report = reports[indexPath.item]
           //When I print(report.name) here. Everything executes correctly 
    
           let viewController = ReportDetailsMapController()
           self.delegate = viewController
           self.delegate?.sendReport(data: report)
    
           self.navigationController?.pushViewController(viewController, animated: true)
        }
    

    However, I think a simpler and more elegant way would be to simply create that property on the ReportDetailsMapController and inject it before pushing it. There's a similar question/answer related to that here: passing data from tableview to viewContoller in swift