0

According to this link , I wanted to pass some data from a B viewController to its parent, A viewController, on back press! here is my code : in my B viewController, I've added this code -

    extension Bcontroller: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {

        (viewController as? Acontroller)?.number = numberInB
        (viewController as? Acontroller)?.myBoolean = boolInB

    }
}

and here is my code in A controller :

override func viewWillAppear(_ animated: Bool) {
    if number != -1 {
        print(myBoolean)
    }
}

when I open B controller, navigationController (willShow) is called, and when I press back button, viewWillAppear is called first, and then navigationController(willShow) in B controller is called! so my data is not set, and number will be always -1 . how can I set these variable?

Rashed
  • 2,349
  • 11
  • 26
Azin Nilchi
  • 849
  • 1
  • 10
  • 24

4 Answers4

2

Please find the below steps to implement delegate.

Step 1:- Initialise the protocol in view controller B.

ViewcontrollerB.m

protocol ViewControllerDelegate
{
    func didUpdateViewController(_ number: NSNumber, myBoolean: Bool);
}

Step 2:- initalise object inside viewcontrollerB

var delegate:ViewControllerDelegate?

Step 3:- Now call this delegate from back function.Here I am considering back is the function to pop viewcontroller.

func Back()
{
    delegate?.didUpdateViewController(numberInB!, myBoolean: boolInB!)
}

Step 4:- Inherit the protocol in viewcontrollerA.

class ViewControllerA: UIViewController,ViewControllerDelegate

Step 5:- Now Set the delegate in viewcontrollerA.

ViewcontrollerA.m

override func viewDidLoad() {
    super.viewDidLoad()
    let obj = ViewControllerB()//Initialize it as per your code
    obj.delegate = self;
    // Do any additional setup after loading the view, typically from a nib.
}

Final Step:- override the delegate method.

   func didUpdateViewController(_ number: NSNumber, myBoolean: Bool) {
        print(number,myBoolean)
    }

Let me know if it worked

ketaki Damale
  • 634
  • 7
  • 25
1

Do call it in viewWillDisappear of controller B:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)

    let navigationController: UINavigationController = self.navigationController!

    let controllers: [Acontroller] = navigationController.viewControllers.filter({ $0 is Acontroller }) as! [Acontroller]

    if let viewController: Acontroller = controllers.first {
        viewController.number = numberInB
        viewController.myBoolean = boolInB
    }
}

If the controller is in stack the values will be assigned to it.

sinner
  • 483
  • 3
  • 14
1

If it is a small data then use UserDefaults:

This is how you store data:

UserDefaults.standard.set(1, forKey: "Key")

And this is how you get it back:

UserDefaults.standard.integer(forKey: "Key")

Or you can use a struct with a static variable:

struct ShareValue {
    static var UserNum: Int = 0
}
Maihan Nijat
  • 9,054
  • 11
  • 62
  • 110
1

Create a delegate which other view controllers can implement and call the delegate method in viewWillDisappear when isMovingFromParentViewController is true

public protocol YourViewControllerDelegate: class {
    func didGoBack(viewController: YourViewController)
}

public class YourViewController: UIViewController {
    public weak var delegate: YourViewControllerDelegate?

    public override func viewWillDisappear(_ animated: Bool) {
        if isMovingFromParentViewController {
            delegate?.didGoBack(viewController: self)
        }
    }
}

In your other view controller:

extension YourOtherViewController: YourViewControllerDelegate {
    public func didGoBack(viewController: YourViewController) {
        // Do something e.g. set your variables
    }
} 
Au Ris
  • 4,541
  • 2
  • 26
  • 53