Modifing One Variable from Another View Controller Swift

Swift - change variable in another view controller, without knowing the class name?

This is what protocols are for: defining a common language between classes when you don't want to share their exact name.

You could define a CommonVariable protocol that describes a variable string:

protocol CommonVariable: class {
var variable: String { get set }
}

Then edit your ViewController2 definition to conform to this protocol:

class ViewController2: UIViewController, CommonVariable {
var variable = ""
}

And edit your ViewController1 method to accept a CommonVariable as the parameter:

class ViewController1: UIViewController {
func changeVariable(controller: CommonVariable) {
controller.variable = "Hello"
}
}

Now this method knows nothing about controller except that it's a class with a string called variable.

As a result, you will be able to call the method from ViewController2 without knowing the class name:

func someFunc() {
viewController1.changeVariable(controller: self)
}

As a side note, CommonVariable, variable, ViewController1, and ViewController2 are all bad names. Not sure if you're actually using these names, but you should aim for something more descriptive.

Modifing one variable from another view controller swift

2 - "prepareForSegue" is called when you push a new view controller via the segue, but not when you dismiss it. No segue is called upon dismissal.

1 - A good way to do this would be the delegate pattern.

So the main view controller would be the delegate for the currencyViewController, and would receive a message when that controller is dismissed.

In the start of the currencyViewController file you prepare the delegate:

protocol CurrencyViewControllerDelegate {
func currencyViewControllerDidSelect(value: String)
}

and you add a variable to the currencyViewController:

var delegate : CurrencyViewControllerDelegate?

Now, the mainViewController has to conform to that protocol and answer to that function:

class MainViewController : UIViewController, CurrencyViewControllerDelegate {
//...

func currencyViewControllerDidSelect(value: String) {
//do your stuff here
}
}

And everything is prepared. Last steps, in prepareForSegue (MainViewController), you will set the delegate of the currencyViewController:

var currencyVC = segue.destinationViewController as CurrencyViewController
currencyVC.delegate = self;

And when the user selects the value in currencyViewController, just call that function in the delegate:

self.delegate?.currencyViewControllerDidSelect("stuff")

A bit complex maybe, but it's a very useful pattern :) here is a nice tutorial with more info if you want it:

http://www.raywenderlich.com/75289/swift-tutorial-part-3-tuples-protocols-delegates-table-views

Receive changing data into another controller Swift

You need to add an observer and keep reference to the destination view controller to keep passing in the new value that has been changed to the destination view controller. Here's how:

class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
var distanta1 = String(byteArray[0]) {
didSet {
destinatieVC?.distance1 = distanta1
}
}
//...
var destinatieVC: SensorViewViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToSenzori" {
destinatieVC = segue.destination as? SensorViewViewController
}
}
}

In SensorViewViewController:

var distance1: String? {
didSet {
print(distance1 ?? "")
}
}

Better approach: Set the destinatieVC?.distanta1.text = distanta1 directly if you're not doing anything else in the didSet block avoid the distance1 property entirely.

Using variables from one View Controller in another

I'd suggest a 3rd class to abstract Player info and make it Singleton. Something like this:

class Players {
static let shared = Players()

var one: String {
get {
return UserDefaults.standard.object(forKey: "playerone") as? String ?? ""
}
set(newValue) {
UserDefaults.standard.set(newValue, forKey: "playerone")
}
}
}

And access/set same like this:

Players.shared.one = "Name one"
print(Players.shared.one)

Swift: Change value of another ViewController with delegation programmatically

You should not create a new ViewController instance each time you call ViewController2.addCreditsToCounter, you already have a ViewController that creates a ViewController2 instance in ViewController.changeView. Just store a weak reference to ViewController in ViewController2 using delegate. In such case ViewController (not ViewController2) should conform to AddCreditsDelegate.
First of all, replace

protocol AddCreditsDelegate {
func addCreditsToCounter()
}

with

protocol AddCreditsDelegate: AnyObject {
func addCreditsToCounter()
}

Then add weak var delegate: AddCreditsDelegate? to ViewController2 and remove ViewController.delegate. Remove ViewController2.addCreditsToCounter, ViewController2 should not conform to AddCreditsDelegate. It means that in ViewController2.addCreditsButton you should call delegate?.addCreditsToCounter(), not addCreditsToCounter().

ViewController should conform to AddCreditsDelegate:

extension ViewController: AddCreditsDelegate {
func addCreditsToCounter() {
counterView.creditPointValue += 5
print("pressed")
}
}

And don't forget to initialize ViewController2.delegate. Replace your ViewController.changeView implementation with

let controller = ViewController2()
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)

How to pass a (changing) variable between two view controllers?

Use a delegate pattern.

In VC2:

protocol VC2Delegate: AnyObject {
var id2: Int { get }
}

class VC2 {
weak var delegate: VC2Delegate?

override func viewDidLoad() {
super.viewDidLoad()
print(delegate?.id2)
}
}

In VC1:

class VC1: UIViewController, VC2Delegate {
...
var id2: Int = 0

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let vc2 = segue.destination as? navigationScreenVC else { return }
vc2.delegate = self
}
...
}

Variable value of a ViewController is changed by forward ViewController when passed parameter

When you assign a SaleOrder to the second view controller you are passing a reference to the SaleOrder instead of a copy.

That means whenever you update the SaleOrder on the second screen you are updating the same SaleOrder used by the first one.

I think simply changing it to let instead of var in the first screen might fix it.
You can also try passing a copy of the object instead of a reference with saleOrder!.copy(), though I think your SaleOrder class will need to conform to the NSCopying protocol.

If you want to learn more about reference types you can read this topic Is Swift Pass By Value or Pass By Reference



Related Topics



Leave a reply



Submit