Search code examples
iosswiftuinavigationcontrollerpass-datapoptoviewcontroller

use popToRootViewController and pass Data


I'm applying for a junior developer position and I've got a very specific task, that already took me 3 days to complete. Sounds easy - pass data to rootViewController. That's what I've done:

1)

   private func userDefaultsToRootController() {
        let input = textField.text!
        defaults.set(input, forKey: "SavedLabel")
        navigationController?.popViewController(animated: true)
    } 
  1. private func segueToRootViewController() { let destinationVC = MainScreen1() let input = textField.text!

      if input == "" { self.navigationController?.popToRootViewController(animated: true) }
    
      destinationVC.input = input
      navigationController?.pushViewController(destinationVC, animated: true)
    

    }

private func popToNavigationController() {
    let input = textField.text!
    if let rootVC = navigationController?.viewControllers.first as? MainScreen1 {
        rootVC.input = input
    }
    navigationController?.popToRootViewController(animated: true)
}
  1. I've used CoreData

But here is the difficult part - I've got an email, that all these methods are not good enough and I need to use delegate and closure. I've done delegation and closures before, but when I popToRootViewController delegate method passes nil. Could you at least point where to find info about this?

** ADDED **

There are 2 View Controllers: Initial and Second one. That's what I have in the Initial View Controller:

var secondVC = MainScreen2()

override func viewDidLoad() {
        super.viewDidLoad()     
        secondVC.delegate = self
    }

That's how I push SecondViewController

@objc private func buttonTapped(_ sender: CustomButton) {
        
        let nextViewController = MainScreen2()
        navigationController?.pushViewController(nextViewController, animated: true)
                
    }

In SecondViewController I've got this protocol

protocol PassData {
    func transferData(text: String)
}

Also a delegate:

var delegate: PassData?

This is how I go back to initial view controller

@objc private func buttonTapped(_ sender: CustomButton) {
        
        if let input = textField.text {
            print(input)
            self.delegate?.transferData(text: input)
            self.navigationController?.popToRootViewController(animated: true)
        }
        
    }

Back to the Initial view controller where I've implemented delegate method

extension MainScreen1: PassData {
    func transferData(text: String) {
        print("delegate called")
        label.text = text
        
    }
}

Delegate doesn't get called.


Solution

  • BASED ON YOUR EDIT:

    You must set the delegate in buttonTapped

    @objc private func buttonTapped(_ sender: CustomButton) {
        
        let nextViewController = MainScreen2()
        nextViewController.delegate = self // HERE WHERE YOU SET THE DELEGATE
        navigationController?.pushViewController(nextViewController, animated: true)
                
    }
    

    You can delete the second instance and your code in viewDidLoad. That's not the instance you push.

    This should point you in the right direction to use delegation and completion handler.

    protocol YourDelegateName {
       func passData(data:YourDataType)
    }
    
    class SecondViewController: UIViewController {
    
      var delegate: YourDelegateName?
    
      func passDataFromSecondViewController(){
    
         YourCoreDataClass.shared.getCoreData { (yourStringsArray) in
         self.delegate?.passData(data: yourStringsArray)
         self.navigationController?.popToRootViewController(animated: true)
         }
      }
    
    class InitialViewController: UIViewController, YourDelegateName {
    
    
       override func viewDidLoad() {
          super.viewDidLoad()
          // or whenever you instantiate your SecondViewController
          let secondViewController = SecondViewController()
          secondViewController.delegate = self //VERY IMPORTANT, MANY MISS THIS 
          self.navigationController?.pushViewController(createVC, animated: true)
        }
    
    
       func passData(data:YourDataType){
           //user your data
       }
    
    }
    
    
    class YourCoreDataClass: NSObject {
        
         static let  shared = YourCoreDataClass()
    
         func getCoreData (completion: ([String]) -> ()){
            ........... your code 
             let yourStringsArray = [String]() // let's use as example an array of strings
             //when you got the data your want to pass
             completion(yourStringsArray)
          }
    }