当前位置: 动力学知识库 > 问答 > 编程问答 >

ios - Trying to understand protocol/delegates in Swift

问题描述:

I'm new to programming & Swift and I am trying to understand how to pass data between two view controllers (no segue) with protocols and delegates.

I have a View Controller (VIEW A) which has a text field and button. When the user hits that button, it should then show that text in a label in another View Controller (VIEW B).

I cannot get the label to show the text - I would appreciate an explanation of what is required to make this work.

Thanks so much!

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

}

}

网友答案:

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

Now, to pass data to another object, your first requirement is to have a reference between them. This reference can be setup in either direction.

One possibility is to have ViewControllerA keep a reference to ViewControllerB. Through this reference, ViewControllerA can call a method on ViewControllerB when the button is pressed which takes that 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)
    }
}

The other possibility, is to use a delegate pattern like your title suggests. This would involve ViewControllerB having a reference to ViewControllerA. Preferably, this would not be with direct knowledge of the ViewControllerA class, but instead through a protocol. The protocol would define a method that returns the data you want to "pass" to ViewControllerB. That way, ViewContollerB can call the protocol method on its "delegate" (which would happen 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 circumstance. The delegate pattern is better to keep your objects less coupled together, but if you are already needing to "trigger" things to happen on ViewControllerB from ViewControllerA then the more direct method is probably required.

分享给朋友:
您可能感兴趣的文章:
随机阅读: