1

I've stucked on a simple concept(I guess), basically I have two ViewControllers on Storyboard also I have 2 classes, ViewController and ViewController2:

I Have a Label whit a default value (0), and when I click on button I want to change the value for this variable to 10, and then I click on the button "Show" and I print this variable, I'm successfully changing the Label and printing the new Value.

The real problem is when I want to get the new variable value from another view, even after I change the value if I try to print the variable on second view the variable always return de default value(0)

enter image description here

ViewController

import UIKit

class ViewController: UIViewController {

var variable = "0"
@IBOutlet var defaultLabel: UILabel!
@IBOutlet var label1Label: UILabel!

@IBAction func setValue(sender: AnyObject) {
    setValue()
}


@IBAction func getValue(sender: AnyObject) {
    getValue()
}
override func viewDidLoad() {
    super.viewDidLoad()
}

func setValue(){
    variable = "10"
    defaultLabel.text = variable
}

func getValue(){
    print(variable)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}


}

ViewController2

import UIKit

class ViewController2: UIViewController {

@IBOutlet var label2Label: UILabel!
override func viewDidLoad() {
    super.viewDidLoad()

}

@IBAction func show(sender: AnyObject) {
 print(ViewController().getValue())

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}
}

I've found this post:

Access variable in different class - Swift

And I really think this is the way that I will find my solution but I really don't understand how to call the variable on ViewController2.

Thanks.

Community
  • 1
  • 1

2 Answers2

1
@IBAction func show(sender: AnyObject) { 
    print(ViewController().getValue())
}

ViewController() - this is class constructor and each time you call ViewController() it return a new instance/object of ViewController class, with default values of course.

If you show ViewController2 from ViewController you can create a property/variable variable2 like variable in ViewController and set value before display, but after ViewController2 is created. If you use segues you can put this code in ViewController class:

// Put this code in ViewController class
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let viewController2 = segue.destinationViewController as? ViewController2
    if viewController2 != nil {
        // you can't set the value for label at this time 
        // because the viewcontroller and all its UI controls aren't loaded
        // but you can set a non UI variable
        viewController2?.variable2 = self.variable 
    }       
}

After that you can put one line of code in viewDidLoad method from ViewController2 class:

// Put this code in ViewController2 class
var variable2 = "0"
@IBOutlet var label2Label: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    self.label2Label.text = variable2
}
Iurie Manea
  • 1,217
  • 10
  • 16
  • I think I've understood what you proposed, the problem is that I'm working with a container View, so the prepareForsegue is done before any interation, even before I set the new variable value. But I'will explore your logic a little bit more if i can solution my problem, Thanks. – Marcelo Pontes Machado Sep 30 '15 at 13:42
0

Use Delegates!

Here's an example where ViewController1 is the delegate for ViewController2:

  1. Define a protocol:

    protocol VariableManager {
      func getValue() -> Int
    }
    
  2. Then, in ViewController1, modify the getValue method so that ViewController1 conforms to the protocol:

    class ViewController1: VariableManager {
    
      func getValue() -> String {
       return variable
      }
    
    }
    
  3. Now define a variable in ViewController2 named delegate:

    class ViewController2 {
      var delegate: VariableManager?
    }
    
  4. In your prepareForSegue method in ViewController1 :

    override func prepareForSegue(segue: UIStoryboardSegue) {
    
      if let identifier  = segue.identifier {
    
        switch identifier {
          case "MySegueIdentifier":
            let destination = segue.destinationViewController as! 'ViewController2'
            destination.delegate = self
    
        default:
          break
        }
    
      }
    
    }
    
  5. Now in ViewController2, change the show method:

    @IBAction func show(sender: AnyObject) {
      if let delegate = delegate {
        let variable = delegate.getValue()
        print(variable)
    }
    

Delegation is a very common, and very important pattern. I suggest you read up on it: https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html

Trying to instantiate another instant of ViewController1 inside ViewController2 is not good practice.

David Smith
  • 356
  • 4
  • 5
  • Thanks for the answer, it clarified to me a little bit more, but I'm still having a problem on this line //destination.delegate = self (cannot assign a value of type 'View Controller' to a value of type 'VariableManager?') – Marcelo Pontes Machado Sep 30 '15 at 01:52
  • The line you're probably missing is `class ViewController1: VariableManager`. You need to specify that `ViewController` conforms to the `VariableManager` protocol. – David Smith Oct 04 '15 at 02:21