【问题标题】:NotificationCenter to pass data in SwiftNotificationCenter 在 Swift 中传递数据
【发布时间】:2017-02-22 06:25:23
【问题描述】:

我正在使用 Swift 3 进行测试项目。我正在尝试使用 NotificationCenter 将 textField 字符串从一个类传递到另一个类。我正在尝试通过此链接来锻炼答案:pass NSString variable to other class with NSNotificationhow to pass multiple values with a notification in 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)

}

}

//SecondVC

 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。

【问题讨论】:

标签: ios swift uiviewcontroller nsnotificationcenter


【解决方案1】:

不要使用对象参数来传递数据。它旨在过滤具有相同名称但来自特定对象的通知。因此,如果您在发布通知时传递某个对象,而在 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)")
}

【讨论】:

  • @alex 我刚刚从您的答案中更新了代码。不过,我没有得到任何结果。你能看看更新吗....谢谢
  • 您在选择器末尾错过了(_:)
  • @Joe 我已经更新了答案,提供了有关如何定义通知名称的更多详细信息。另请注意,您必须在某些时候 removeObserver。
  • @alex 我实施了您更新的答案。仍然没有任何反应。我不知道我错过了什么。我想知道我需要导入任何代表等......谢谢
【解决方案2】:

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


}

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 我会在 if 语句中添加一条日志消息。这样您可以更早地发现潜在错误。
    • @MaksymMusiienko 我刚刚从您的回答中更新了代码。不过,我没有得到任何结果。你能看看更新吗....谢谢
    • @MaksymMusiienko 您的回答具有误导性,object 属性不应该这样使用。
    • 将您的 addObserver 方法更改为 NotificationCenter.default.addObserver(self, selector: #selector(self.incomingNotification(_:)), name: NSNotification.Name(rawValue: "NOTIFICATION_NAME"), object: nil)。此外,请尝试对通知使用不言自明的名称。另一种传递数据的正确方法是使用 userInfo。
    【解决方案4】:

    使用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)        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-22
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-29
      • 2017-02-10
      • 1970-01-01
      相关资源
      最近更新 更多