himi himi - 1 month ago 7
Swift Question

Container view losing textField values when a button is tapped in the parent viewController

I have a viewController with a

UISegmentedControl
and a
UIButton
.
Within this viewController, I have two containers, each containing one viewController with a
UITextField
inside.

enter image description here

I want to save the values in the textField on the click of the button.

Here's the code I have written so far:

View Controller:

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//
//

containerA.showView()
containerB.hideView()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

@IBAction func buttonTapped(sender: UIButton) {
print(ContainerAViewController.sharedInstance.textFieldA)


}
@IBAction func segmentedControlValueChanged(sender: AnyObject) {
switch(sender.selectedSegmentIndex) {
case 0 : containerA.showView()
containerB.hideView()

case 1 : containerB.showView()
containerA.hideView()

default : containerA.showView()
containerB.hideView()

}
}

@IBOutlet weak var containerA: UIView!
@IBOutlet weak var containerB: UIView!


func hideView(view: UIView) {
view.userInteractionEnabled = false
view.hidden = true
}

func showView(view: UIView) {
view.userInteractionEnabled = true
view.hidden = false
}

}


extension UIView {
func hideView() -> UIView {
self.userInteractionEnabled = false
self.hidden = true
return self
}

func showView() -> UIView {
self.userInteractionEnabled = true
self.hidden = false
return self
}

}


ContainerAViewController:

class ContainerAViewController: UIViewController {

@IBOutlet weak var textFieldA: UITextField!

static let sharedInstance = ContainerAViewController()

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
}
}


ContainerBViewController:

class ContainerBViewController: UIViewController {

@IBOutlet weak var textFieldB: UITextField!

static let sharedInstance = ContainerBViewController()


override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
}
}


When I tap the button, it gives me the following error:


fatal error: unexpectedly found nil while unwrapping an Optional value


Can somebody please help?

Answer

You should not try to manipulate another view controller's views. That violates the principle of encapsulation, an important principle in object-oriented development.

You should give your child view controllers (ContainerAViewController and ContainerBViewController) string properties, and have the code for those view controllers set that string property when the user enters text into the view controllers' text fields.

Ignoring that design flaw, your code doesn't make sense. You show your CLASS as ContainerAViewController, and yet your buttonTapped method is trying to ask a ContainerAViewController singleton for the value of a text field. That makes no sense.

You want to have properties in your parent view controller that point to your child view controllers.

You should implement a prepareForSegue method in your parent view controller, and in that prepareForSegue method, look for the embed segues that fire when the child view controllers are loaded. When that happens you should set your properties that point to the child view controllers.

Comments