【问题标题】:Trying to understand protocol/delegates in Swift试图理解 Swift 中的协议/委托
【发布时间】:2014-08-31 05:37:35
【问题描述】:

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

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

我无法让标签显示文本 - 我希望能解释一下完成这项工作所需的条件。

非常感谢!

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

【问题讨论】:

    标签: ios xcode delegates swift protocols


    【解决方案1】:

    首先,请注意:您的视图控制器名称应在名称中包含“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?
    
        override func viewDidLoad() {
            if let actualDelegate = self.delegate {
                self.theLabel.text = actualDelegate.requiredText()
            }
        }
    }
    

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

    【讨论】:

    • 感谢@drewag 的帮助!
    • “直接”方法不会创建一个全新的 ViewControllerB 实例吗?此外,我不得不使用 'var tabbarViewController : TabBarViewController = TabBarViewController()' 而不是你说的方式不起作用(变量保持为零)
    • @ByronCoetsee & OP,你们是否有任何资源更深入地了解采用哪种方法?什么时候需要耦合?等谢谢!
    猜你喜欢
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多