【问题标题】:How to use delegates properly in Swift?如何在 Swift 中正确使用委托?
【发布时间】:2016-03-02 14:11:00
【问题描述】:

我阅读了很多关于代表的信息,但实际上我无法正确使用它。

描述:我有A: UIViewControllerB: UIViewC: UIViewController。我想从A: UIViewControllerC: UIViewControllerB: UIView 内部运行segue。

我试过了:

protocol SegueDelegate {
    func runSegue(identifier: String)
}

class B: UIView { ... }

在我的A: UIViewController

override func viewDidLoad() {
    B().delegate = self
}

func runSegue(identifier: String) {
    self.performSegueWithIdentifier(identifier, sender: self)
}

并尝试通过以下方式调用它:

@IBAction func send(sender: AnyObject) {
    let a: SegueDelegate? = nil
    a!.runSegue("goToMainPage")
}

但我确定我没有正确使用它。有人可以帮我吗?我不想要一个答案。请简要描述一下它的概念

【问题讨论】:

    标签: ios swift uiviewcontroller delegates protocols


    【解决方案1】:

    委托只是一种设计模式,您可以通过多种方式使用它。您可以查看 Apple 框架以了解如何以及在何处使用委托作为示例。表格视图委托可能是 UIKit 中最著名的委托。

    委托用作代码与未知类的实例通信的回调机制,而无需知道该实例将响应委托协议的方法。

    委托的替代方法是使用闭包(我们过去在 Objective-C 中称为块)。何时使用一个与另一个是一个品味问题。有一些经验法则,例如outlined here

    IMO,您正在做的是使用代表的正确方法。您通过委托将视图功能与视图控制器的功能分开,因此您的视图的约定很明确:用户需要响应委托方法。

    您的代码有效且正确。我在这里做了一个快速的实现:https://github.com/kristofvanlandschoot/DelegateUsage/tree/master

    与您的示例的主要区别,也许就是您犯错的地方是您的代码的第三部分,您应该在其中编写如下内容:

    @IBAction func send(sender: AnyObject) {
        delegate?.runSegue("segueAB")
    }
    

    【讨论】:

    • 非常感谢您提供的示例!我只想问一下这条线:self.viewWithDelegate.delegate = self。我无法将视图设置为委托self.view.delegate。需要我为此做一些额外的事情还是我理解错了?
    • 不确定我是否完全理解您的问题。 ViewControllerA 需要设置 viewWithDelegate 的委托。 viewWithDelegate 怎么知道如何获取委托?
    【解决方案2】:

    您的代码中有多个错误,例如:

    在这里,您正在创建一个新 B,并将 A 设置为该新实例的代表,而不是您真正想要的那个

    override func viewDidLoad() {
        «B()».delegate = self
    }
    

    在这里,您正在创建力展开 nil 值

    @IBAction func send(sender: AnyObject) {
        let a: SegueDelegate? = «nil»
        «a!».runSegue("goToMainPage")
    }
    

    如果你想做的是告诉 A 从 B 内部执行到 C 的 segue,你需要做的就是在 A 上调用 performSegueWithIdentifier

    例如:

    class B: UIView {
        weak var referenceToA: UIViewController? = nil // set this somewhere
        @IBAction func send(sender: AnyObject) {
            guard let a = referenceToA else {
                fatalError("you didn't set the reference to a view controller of class A")
            }
            a.performSegueWithIdentifier("goToMainPage", sender: self)
        }
    }
    

    【讨论】:

    • 需要将weak var referenceToA: UIViewController? = nil 更改为我自己的ViewController 类还是需要保存UIViewController
    • 用你的代码我得到下一个错误fatal error: you didn't set the reference to a variable:在线fatalError("you didn't set the reference to a variable")
    • 没关系,你自己的类是 UIViewController 的子类,你要使用的方法是所有 UIViewController 通用的,所以不用改变它就可以工作。但如果你改变它,那也没关系
    • 当然你会得到那个错误,我把它放在那里是因为我需要你在某个地方设置那个变量。
    • 哦,我复制了你的代码。好像没看懂
    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 2010-11-16
    • 2013-12-20
    • 2016-05-13
    相关资源
    最近更新 更多