0

I am having a problem with passing data between ViewControllers as an action. This shall mean following:

ViewController1 - NavigationControllers, etc. - ...
                                                 |
                                                 |
ViewController2    -     -    -    -    -   -   ...

So I have two ViewControllers. ViewController1 has a variable (let's say var myName:String = "Joana") and I want to change it by clicking on a button in the ViewController2. My question is: How can I do that (I know how to pass data between VCs which are directly connected via a segue, but not combined with an action, that's my problem)? I've heard of prepare(for segue: UIStoryboardSegue, sender: Any?), but I think that it only works if there exists a segue (directly) between both VCs. Summarised:

VC2: Button: action -> change var 'myname' on VC1 to 'hello', no direct segue.

Thanks for your help in advance! :-)

j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38
  • you can create by code a segue to go back to view controller 1 and pass the data, or you can have a class, and edit a class, and since class are reference type, change it in one place will change it in another place. – Mago Nicolas Palacios May 10 '17 at 19:44
  • If the ViewController1 object is still in memory when the button is pressed, you can send it a notification and attach data as the notification object or the user info dictionary. – Phillip Mills May 10 '17 at 19:47
  • Actually there are many ways to do that. You can use notifications, delegates, singleton class... – Vah.Sah May 10 '17 at 19:50
  • Ok, thank you all, I'll have a look at it and write you back when I found the best solution – j3141592653589793238 May 10 '17 at 20:11

2 Answers2

0

Look at it:

class FirstVC: UIViewController {
    var someAttribute: String = "ola!"

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard let segueIdentifier = segue.identifier else { return }
        if segueIdentifier == "YourSegueIdentifierFromStoryBoard" {
            guard let viewController = segue.destination as? SecondVC else { return }
            // someAttribute == "ola!"
            viewController.someButtonTappedHandler = { [weak self] (newValue) in
                guard let strongSelf = self else { return }
                strongSelf.someAttribute = newValue
                // someAttribute == "Bla Bla Bla!"
            }
        }
    }
}

class SecondVC: UIViewController {
    var someButtonTappedHandler: ((String) -> Void)?

    @IBAction func someButtonTapped() {
        if let handler = someButtonTappedHandler {
            handler("Bla Bla Bla!")
        }
    }
}
Vasilii Muravev
  • 3,063
  • 17
  • 45
0

I now solved my problem as following:

final class Singleton{
    private init(){ }

    static let shared = Singleton()

    var someInt: Int = Int()
}

So I declare a singleton. Next:

class ViewControllerOne: UIViewController{
    [Outlets,...]
    override func viewDidLoad() {
        super.viewDidLoad()

        let integer = Singleton.shared.someInt
        print("We're in Class: ViewController and Singleton.shared.someInt = \(integer).\n")
        Singleton.shared.someInt = integer
        myLabel.text = "\(Singleton.shared.someInt)"
    }
}

Second VC:

class ViewControllerTwo: UIViewController{
    [...]
    override func viewDidLoad() {
            super.viewDidLoad()

            let integer = Singleton.shared.someInt
            print("We're in Class: SecondVC and Singleton.shared.someInt = \(integer).\n")
            Singleton.shared.someInt = 5
            if Singleton.shared.someInt == 5{
                print("Singleton.shared.someInt changed to 5 in Class SecondVC.\n")
            }

        }
}

My storyboard looks like this:

The storyboard

Let me know if there are any mistakes, but it works for me.

Another link where I also found help:

Help

Community
  • 1
  • 1
j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38