Trying to understand protocol / delegates in Swift

I am new to programming and Swift, and I am trying to figure out how to transfer data between two view controllers (no segue) with protocols and delegates.

I have a View Controller (VIEW A) that has a text box and a button. When the user clicks on this button, he should then display this text in a label in another view controller (VIEW B).

I cannot get a shortcut to show the text - I would appreciate an explanation of what is required to complete this work.

Many thanks!

import UIKit protocol sendNameToViewB { func showNameLabel(name:String) } class ViewA: UIViewController { var delegate: sendNameToViewB? @IBOutlet weak var textField: UITextField! @IBAction func addButton(sender: AnyObject) { delegate?.showNameLabel(textField.text) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } class ViewB: UIViewController, sendNameToViewB { @IBOutlet weak var theLabel: UILabel! func showNameLabel(name: String) { theLabel.text = name } } 

VIEW CONTROLLERS

+7
ios xcode swift protocols delegates
source share
1 answer

First, note:. Your names for view controllers should include a "ViewController". There is a completely different collection of classes inheriting from UIView . Naming the view controller simply ViewA makes it look like your class is just a view instead of a view controller. Views are in a completely different layer of your application.

Now, to transfer data to another object , your first requirement is to have a link between them. This link can be configured in any direction.

One possibility is for ViewControllerA to maintain a link to ViewControllerB. Using this link, ViewControllerA can invoke a method on ViewControllerB when a button is pressed that accepts the data you want to pass as an argument.

 class ViewControllerA: UIViewController { @IBOutlet weak var viewControllerB: ViewControllerB! @IBAction func addButton(sender: AnyObject) { self.viewControllerB.showNameLabel(textField.text) } } 

Another possibility is to use a delegate template, as your header suggests. This will include ViewControllerB with reference to ViewControllerA. Preferably, this is not due to direct knowledge of the ViewControllerA class, but instead through the protocol. The protocol will define a method that returns the data you want to pass to ViewControllerB. Thus, ViewContollerB can call the protocol method in its "delete" (which is likely to be ViewControllerA) to get the data it needs.

 protocol ViewControllerBDelegate { func requiredText() -> String } class ViewControllerB: UIViewController { @IBOutlet weak var delegate: ViewControllerBDelegate? override func viewDidLoad() { if let actualDelegate = self.delegate { self.theLabel.text = actualDelegate.requiredText() } } } 

Which method you choose really depends on what you need in this case. In a delegate template, it's best to keep your objects less connected to each other, but if you already need to “run” something that needs to happen on ViewControllerB from ViewControllerA, you may need a more direct method.

+8
source share

All Articles