简体   繁体   English

NotificationCenter 在 Swift 传递数据

[英]NotificationCenter to pass data in Swift

I am working on a test project in Swift 3. I am trying to pass textField string from one class to another class using NotificationCenter.我正在 Swift 中进行测试项目 3. 我正在尝试使用 NotificationCenter 将 textField 字符串从一个 class 传递到另一个 class。 I am trying to workout the answer from this link: pass NSString variable to other class with NSNotification and how to pass multiple values with a notification in swift我正在尝试从此链接中找出答案: 使用 NSNotification 将 NSString 变量传递给其他 class以及如何通过 swift 中的通知传递多个值

I tried few answers from the above link but nothing worked.我从上面的链接尝试了几个答案,但没有任何效果。

My code:我的代码:

//First VC //第一个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)

}

}

//SecondVC //第二个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
}

在此处输入图像描述 } }

I am not sure whats wrong with the code.我不确定代码有什么问题。 Above, code originally marked as a answered which, I found from the first link.上面,我从第一个链接找到的最初标记为已回答的代码。 Code been converted to Swift.代码已转换为 Swift。

Don't use object parameter to pass data. 不要使用object参数传递数据。 It is meant to filter notifications with the same name, but from a particular object. 它旨在过滤具有相同名称但来自特定对象的通知。 So if you pass some object when you post a notification and another object when you addObserver, you won't receive it. 因此,如果在addObserver发布通知和另一个对象时传递了一些对象,则不会收到它。 If you pass nil, you basically turn off this filter. 如果你传递nil,你基本上会关闭这个过滤器。

You should use userInfo parameter instead. 您应该使用userInfo参数。

First, it is better to define notification's name as extension for Notification.Name. 首先,最好将通知的名称定义为Notification.Name的扩展名。 This approach is much safer and more readable: 这种方法更安全,更易读:

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

Post notification: 发布通知:

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

Subscribe: 订阅:

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

Unsubscribe: 退订:

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

Method to be called: 要调用的方法:

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

Pass text using userInfo which is a optional Dictionary of type [AnyHashable:Any]? 使用userInfo传递文本, userInfo是类型为[AnyHashable:Any]的可选字典? in Swift 3.0 and it is [NSObject : AnyObject]? 在Swift 3.0中它是[NSObject:AnyObject]? in swift 2.0 在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

}

in viewDidLoad viewDidLoad

// Register to receive notification //注册接收通知

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

and in incomingNotification 并在incomingNotification中

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


}

In your sendData method pass textField.text into Notification object and in your incomingNotification do this: sendData方法中,将textField.text传递给Notification对象,并在incomingNotification执行以下操作:

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

resultLabel.text = theString

You can also use blocks to pass data between controllers. 您还可以使用块在控制器之间传递数据。

Use dispatchQueue because your notification is posting before your view load. 使用dispatchQueue是因为您的通知是在视图加载之前发布的。 Therefore just give delay in your notification Post. 因此,只需延迟通知发布。

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

}

Just use NotificationCenter to send and receive the notification that state changed.只需使用 NotificationCenter 发送和接收 state 更改的通知即可。 Pass the data through some a data model such as an ObservableObject (particularly if you're bridging between SwiftUI and UIKit).通过一些数据 model 传递数据,例如 ObservableObject(特别是如果您在 SwiftUI 和 UIKit 之间桥接)。 Here's are a couple of extension that make it pretty simple for lightweight inter-component signaling without the cumbersome forgettable semantics of NotificationCenter.这里有几个扩展,它们使轻量级组件间信号发送变得非常简单,而没有 NotificationCenter 的繁琐易忘的语义。 (Of course you define your own Notification.Name constants to be meaningful to your purpose). (当然,您可以定义自己的 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)
    }
}

To post a notification is as simple as:发布通知非常简单:

  NotificationCenter.post(.startEditingTitle)

And to receive the notification elsewhere:并在其他地方接收通知:

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

Or to just wait for the notification instead of asynchronously handling it:或者只是等待通知而不是异步处理它:

  NotificationCenter.wait(.startEditingTitle)

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

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