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

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

问题描述

我是编程新手Swift 和我正在尝试了解如何使用协议和委托在两个视图控制器(无 segue)之间传递数据.

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.

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

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.

非常感谢!

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
                }
            }

推荐答案

首先,请注意:您的视图控制器名称中应包含ViewController".从 UIView 继承的类的集合完全不同.仅将视图控制器命名为 ViewA 会使您的类看起来只是一个视图而不是视图控制器.视图位于应用程序的完全不同的层中.

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.

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

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)
    }
}

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

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()
        }
    }
}

您选择哪种方法实际上取决于您在这种情况下需要什么.委托模式可以更好地减少您的对象耦合在一起,但如果您已经需要从 ViewControllerA 触发"在 ViewControllerB 上发生的事情,那么可能需要更直接的方法.

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天全站免登陆