【问题标题】:Set receiving delegate in Swift without segue在没有 segue 的情况下在 Swift 中设置接收委托
【发布时间】:2016-01-04 20:05:53
【问题描述】:

我阅读了一些关于在 Swift 中使用代理的帖子,但大多数情况下,他们建议调用 viewcontroller 来接收带有 segue 的代理。我想知道如何在没有转场的情况下这样做,例如在 TabBar 应用程序中。这是 FirstViewController.swift 的代码

//  FirstViewController.swift

import UIKit

protocol FirstViewControllerDelegate {
    func didSendMessage(message: String)
}

class FirstViewController: UIViewController {

    var delegate: FirstViewControllerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate?.didSendMessage("Hello from FirstViewController")
    }

}

这里是 SecondViewController.swift

//  SecondViewController.swift

import UIKit

class SecondViewController: UIViewController, FirstViewControllerDelegate {

    @IBOutlet weak var secondSubTitleLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // how to set delegate here?
    }

    func didSendMessage(message: String) {
        secondSubTitleLabel.text = message
    }

}

这里应该如何设置接收委托?

【问题讨论】:

    标签: ios iphone swift delegates


    【解决方案1】:

    这通常不是委托适合您想要实现的目标的场景。如果您只是想从 F​​irstViewController 调用 SecondViewController 中的某个方法,您可以通过

    获得参考
    if let vc = self.tabBarController!.viewControllers[1] as? SecondViewController {
       vc.didSendMessage("hello")
    }
    

    或者你可能想发送一个 NSNotification 来避免上面代码引入的紧耦合

    在您的 AppDelegate 中:

    NSNotificationCenter.defaultCenter().postNotification("ReceivedAppWatchData", object: self, userInfo: theData)
    

    在您想要接收数据的任何视图控制器中:

    func viewDidLoad() {
      ...
      // subscribe to notification
      NSNotificationCenter.defaultCenter().addObserver(self, selector: "watchDataReceived:", name: "ReceivedAppWatchData",object: nil)
      ...
    }
    
    func watchDataReceived(notif: NSNotification) {
       // handle data
    }
    
    deinit {
       // unsubscribe to notifications
       NSNotification.defaultCenter().removeObserver(self)
    }
    

    这样任何视图控制器都可以在不知道彼此的情况下访问数据。

    【讨论】:

    • 也许我看错了方向。现实生活场景:我在 AppDelegate.swift 中收到 Apple Watch 数据,并希望在它们进入后立即将它们传递给 UIViewController 实例。标签栏应用程序仅用于测试。我认为代理是要走的路,但我可能错了。
    • 更新了答案以反映另一种方法
    • 谢谢。这适用于测试应用程序!在现实生活中的应用程序中仍然存在一些问题,但这种方法似乎可以满足我的要求!
    【解决方案2】:

    您的标签栏控制器正在控制每个标签的视图控制器,因此您应该在标签栏控制器中设置委托。

    class TabBarController: UITabBarController {
        func viewDidLoad() {
            super.viewDidLoad()
            let firstVC = viewControllers[0] as! FirstViewController
            let secondVC = viewControllers[1] as! SecondViewController
            firstVC.delegate = secondVC
        }
    }
    

    这段代码显然存在一些类型安全问题,并假设viewControllers[0]viewControllers[1] 分别是FirstViewControllerSecondViewController。此外,在此示例中,您应该等待在 viewDidLoad 之后调用委托方法。 SecondViewController 可能尚未加载,也可能尚未加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 2019-01-23
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多