繁体   English   中英

NotificationCenter 在 Swift 传递数据

[英]NotificationCenter to pass data in Swift

我正在 Swift 中进行测试项目 3. 我正在尝试使用 NotificationCenter 将 textField 字符串从一个 class 传递到另一个 class。 我正在尝试从此链接中找出答案: 使用 NSNotification 将 NSString 变量传递给其他 class以及如何通过 swift 中的通知传递多个值

我从上面的链接尝试了几个答案,但没有任何效果。

我的代码:

//第一个VC

import UIKit


extension Notification.Name {        
public static let myNotificationKey = Notification.Name(rawValue: "myNotificationKey")    
}


class ViewController: UIViewController {

@IBOutlet weak var textView: UITextView!

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


@IBAction func sendData(_ sender: AnyObject) {

    let userInfo = [ "text" : textView.text ]
    NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)

}

}

//第二个VC

 import Foundation
 import  UIKit

 class viewTwo: UIViewController {

@IBOutlet weak var result: UILabel!



override func viewDidLoad() {


}


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(self.notificationReceived(_:)), name: .myNotificationKey, object: nil)
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: .myNotificationKey, object: nil)
}

func notificationReceived(_ notification: Notification) {
    guard let text = notification.userInfo?["text"] as? String else { return }
    print ("text: \(text)")

    result.text = text
}

在此处输入图像描述 }

我不确定代码有什么问题。 上面,我从第一个链接找到的最初标记为已回答的代码。 代码已转换为 Swift。

不要使用object参数传递数据。 它旨在过滤具有相同名称但来自特定对象的通知。 因此,如果在addObserver发布通知和另一个对象时传递了一些对象,则不会收到它。 如果你传递nil,你基本上会关闭这个过滤器。

您应该使用userInfo参数。

首先,最好将通知的名称定义为Notification.Name的扩展名。 这种方法更安全,更易读:

extension Notification.Name {        
    public static let myNotificationKey = Notification.Name(rawValue: "myNotificationKey")    
}

发布通知:

let userInfo = [ "text" : text ]
NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)

订阅:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(self.notificationReceived(_:)), name: .myNotificationKey, object: nil)
}

退订:

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: .myNotificationKey, object: nil)
}

要调用的方法:

func notificationReceived(_ notification: Notification) {
    guard let text = notification.userInfo?["text"] as? String else { return }
    print ("text: \(text)")
}

使用userInfo传递文本, userInfo是类型为[AnyHashable:Any]的可选字典? 在Swift 3.0中它是[NSObject:AnyObject]? 在swift 2.0中

@IBAction func sendData(_ sender: UIButton) {

// post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: ["text": textValue.text])

print(textValue) // textValue printing

}

viewDidLoad

//注册接收通知

NotificationCenter.default.addObserver(self, selector: #selector(self. incomingNotification(_:)), name:  NSNotification.Name(rawValue: "notificationName"), object: nil)

并在incomingNotification中

func incomingNotification(_ notification: Notification) {
if let text = notification.userInfo?["text"] as? String {
   print(text)
  // do something with your text   
}


}

sendData方法中,将textField.text传递给Notification对象,并在incomingNotification执行以下操作:

guard let theString = notification.object as? String else {
    print("something went wrong")
    return 
}

resultLabel.text = theString

您还可以使用块在控制器之间传递数据。

使用dispatchQueue是因为您的通知是在视图加载之前发布的。 因此,只需延迟通知发布。

@IBAction func sendData(_ sender: AnyObject) {

    let userInfo = [ "text" : textView.text ]
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
 NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)        }

}

只需使用 NotificationCenter 发送和接收 state 更改的通知即可。 通过一些数据 model 传递数据,例如 ObservableObject(特别是如果您在 SwiftUI 和 UIKit 之间桥接)。 这里有几个扩展,它们使轻量级组件间信号发送变得非常简单,而没有 NotificationCenter 的繁琐易忘的语义。 (当然,您可以定义自己的 Notification.Name 常量以对您的目的有意义)。

extension Notification.Name {
    static let startEditingTitle = Notification.Name("startEditingTitle")
    static let stopEditingTitle  = Notification.Name("stopEditingTitle")
}

extension NotificationCenter {
    static func wait(_ name : Notification.Name) async {
        for await _ in NotificationCenter.default.notifications(named: name) {
            break;
        }
    }
    static func post(_ name : Notification.Name) {
        NotificationCenter.default.post(name: name, object: nil)
    }
    @discardableResult static func postProcessing(_ name: Notification.Name, using block: @escaping (Notification) -> Void) -> NSObjectProtocol {
        NotificationCenter.default.addObserver(forName: name, object: nil, queue: OperationQueue.main, using: block)
    }
}

发布通知非常简单:

  NotificationCenter.post(.startEditingTitle)

并在其他地方接收通知:

  NotificationCenter.postProcessing(.startEditingTitle) (_ in {
      print("Started editing title")
  }

或者只是等待通知而不是异步处理它:

  NotificationCenter.wait(.startEditingTitle)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM