Reputation: 35
I'm trying to pass data from a ViewController
to a Container within it. When I press the button the delegate sends the data to the container but the container resizes. How would I stop this from happening.
I'm thinking a prepareForSegue
function but I can't figure out how to implement it but I don’t know if even that would be a solution.
protocol VCDelegate {
func passData(theData1:String)
}
class ViewController: UIViewController {
var delegate : VCDelegate?
@IBAction func sendTextToContainer(_ sender: Any) {
let ViewC = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
let ContainerV = self.storyboard!.instantiateViewController(withIdentifier: "ContainerView") as! ContainerView
self.present(ContainerV,animated:true,completion: nil)
ViewC.delegate = ContainerV
ViewC.delegate?.passData(theData1:"Hello")
}
}
class ContainerView: UIViewController, VCDelegate {
func passData(theData1: String) {
print(theData1)
theText.text = theData1
}
@IBOutlet weak var theText: UILabel!
override func viewWillAppear(_ animated: Bool) {
}
}
Upvotes: 1
Views: 652
Reputation: 437372
You are instantiating a new, second instance of the child view controller. But if you created a “container” in IB, it’s already been instantiated for you.
There are two ways for the parent view controller to pass data to the child. You can pass the initial data in prepare(for:sender:)
:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? SecondViewControllerProtocol {
destination.passData(string: "Initial value")
}
}
If you want to later update it, you can grab the relevant children
:
@IBAction func didTapButton(_ sender: Any) {
for child in children {
if let child = child as? SecondViewControllerProtocol {
child.passData(string: "Updated value")
}
}
}
(You obviously could save the reference you captured during prepare(for:sender:)
, too, if you wanted.)
The second view controller can then update its label accordingly:
protocol SecondViewControllerProtocol {
func passData(string: String)
}
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
private var string: String?
override func viewDidLoad() {
super.viewDidLoad()
// this is in case you passed the data before the label was hooked up
label.text = string
}
}
extension SecondViewController: SecondViewControllerProtocol {
func passData(string: String) {
self.string = string
guard let label = label else { return }
UIView.transition(with: label, duration: 0.25, options: .transitionCrossDissolve, animations: {
label.text = string
}, completion: nil)
}
}
That yields:
Upvotes: 2