试图了解Swift中的协议/代理 [英] Trying to understand protocol/delegates in Swift

查看:144
本文介绍了试图了解Swift中的协议/代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很习惯编程我试图了解如何在两个视图控制器(没有segue)与协议和代理之间传递数据。



我有一个视图控制器(VIEW A)一个文本字段和按钮。当用户点击该按钮时,应该在另一个视图控制器(VIEW B)中的标签中显示该文本。



我无法获取标签来显示文本 - 我很乐意解释这项工作需要什么。



非常感谢!

  import UIKit 

协议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)

}
覆盖func viewDidLoad(){
super.viewDidLoad()

//加载视图后,通常从笔尖进行任何其他设置。
}
覆盖func didReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
//处理可以重新创建的任何资源。
}


}

class ViewB:UIViewController,sendNameToViewB {

@IBOutlet weak var theLabel:UILabel!

func showNameLabel(name:String){
theLabel.text = name
}
}

解决方案

首先,一个注释:视图控制器的名称应在名称中包含ViewController。有一个完全不同的类继承自 UIView 的集合。命名视图控制器只是 ViewA 使它看起来像你的类只是视图而不是视图控制器。视图与您的应用程序完全不同。



现在,要将数据传递给另一个对象,您的第一个要求是具有引用它们之间。这个参考可以在任一方向设置。



一个可能的办法是让ViewControllerA保留对ViewControllerB的引用。通过此参考,ViewControllerA可以在按下按钮时调用ViewControllerB上的一个方法,该方法将您要传递的数据作为参数。

  class ViewControllerA:UIViewController {
@IBOutlet weak var viewControllerB:ViewControllerB!

@IBAction func addButton(sender:AnyObject){
self.viewControllerB.showNameLabel(textField.text)
}
}

另一种可能性是使用您的标题建议的委托模式。这将涉及ViewControllerB对ViewControllerA的引用。最好不要直接了解ViewControllerA类,而是通过一个协议。该协议将定义一个方法,返回您要传递到ViewControllerB的数据。这样,ViewContollerB可以在其委托(这将恰好是ViewControllerA)上调用协议方法来获取所需的数据。

  protocol ViewControllerBDelegate {
func requiredText() - > String
}

class ViewControllerB:UIViewController {
@IBOutlet weak var delegate:ViewControllerBDelegate?

覆盖func viewDidLoad(){
如果let actualDelegate = self.delegate {
self.theLabel.text = actualDelegate.requiredText()
}
}
}

您选择的方法实际上取决于您在这种情况下需要什么。代理模式更好地保持对象较少耦合在一起,但如果您已经需要从ViewControllerAView触发事件发生,那么可能需要更直接的方法。


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.

这篇关于试图了解Swift中的协议/代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆