NotificationCenter 在从 viewcontroller 发布到另一个 ViewController 时第一次不工作

NotificationCenter is not working first time when it is posted from viewcontroller to another ViewController

我有 2 个 ViewController,分别称为 ViewController1 和 ViewController2。

我正在从 ViewController1 向 ViewController2 发送通知,但在第一次发送时,NotificationCenter 无法正常工作。

当我从 ViewController2 返回到 ViewController1 然后再次尝试移动 ViewController2 时,NotificationCenter 正在工作,

// ViewController1.swift

import UIKit

class ViewController1: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

}

//Move to next VC
@IBAction func nextButtonClicked(_ sender: Any) {

    NotificationCenter.default.post(name: Notification.Name("callMethodPrint1FromVC2"), object: nil)

    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    let vc2 = storyBoard.instantiateViewController(withIdentifier: "ViewController2Id") as? ViewController2
    navigationController?.pushViewController(vc2!, animated: true)

  } 
}

// ViewController2.swift

import UIKit

class ViewController2: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.


}

override func viewWillAppear(_ animated: Bool) {
    //Recieve notification
    NotificationCenter.default.addObserver(self, selector: #selector(self.print1Method(notification:)), name: Notification.Name("callMethodPrint1FromVC2"), object: nil)
}

@objc func print1Method(notification: Notification) {

    print("Notification came from VC 1")
}

@IBAction func backToVC1(_ sender: Any) {

    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    let vc2 = storyBoard.instantiateViewController(withIdentifier: "ViewController1Id") as? ViewController1
    navigationController?.pushViewController(vc2!, animated: true)
}

 //Remove notification object
deinit {

    NotificationCenter.default.removeObserver(self, name: Notification.Name("callMethodPrint1FromVC2"), object: nil)
}

}

实际输出

当我第一次和每次将 ViewController1 移动到 ViewController2 时,都必须调用 ViewController2 的 print1Method 方法。

但它没有按预期工作。 我的代码中是否存在 Anu 问题或者我遗漏了什么?

它不会调用,因为 ViewController2 没有加载,它会第二次调用,因为你在向后移动时正在执行 Push 而不是 Pop,这反过来仍然是内存中的 ViewController1。

而是删除通知并根据您的需要从 ViewController2 Viewdidload/ViewWillappear/Viewdidappear 调用 print1Method。如果要将一些数据从 ViewController1 传递到 ViewController2

,请在 ViewController2 中保留一些 public 变量并在 ViewController1 中的 prepareforsegue 方法中分配值

并替换你的:

@IBAction func backToVC1(_ sender: Any) {

     let storyBoard = UIStoryboard(name: "Main", bundle: nil)
     let vc2 = storyBoard.instantiateViewController(withIdentifier: "ViewController1Id") as? ViewController1
     navigationController?.pushViewController(vc2!, animated: true)
}

@IBAction func backToVC1(_ sender: Any) {
    navigationController?.popViewController(animated: true)
}

您正在 post 在您的视图控制器初始化之前收到通知。

调用vc2的方法不需要post通知。相反,直接调用该方法。

VC1

@IBAction func nextButtonClicked(_ sender: Any) {

     let storyBoard = UIStoryboard(name: "Main", bundle: nil)
     let vc2 = storyBoard.instantiateViewController(withIdentifier:"ViewController2Id") as ViewController2
     vc2.print1Method()
     navigationController?.pushViewController(vc2!, animated: true)

  } 
}

VC2

func print1Method() {

     print("Method called from VC 1")
 }

还有后退按钮,你做错了。只需从堆栈中弹出视图控制器

 @IBAction func backToVC1(_ sender: Any) {

     self.navigationController?.popViewController(animated: true)
 }

只需添加一个步骤即可完成此操作。

我们在这里做的是在导航之前调用主视图控制器的方法addObserver() 来注册观察者,然后我们将发布NotificationCenter.default.post。通过这种方式,观察者首先注册。

First View Controller 中添加这个功能在你的按钮中点击

func navigate(){
    let storyBoard = UIStoryboard(name: "travelApp", bundle: nil)
    let VC = storyBoard.instantiateViewController(identifier: "home") as! homeViewController
    VC.addObserver()
    NotificationCenter.default.post(name:Notification.Name("myNotificationName"), object: nil,  userInfo: ["hello": "world"])
    self.navigationController?.pushViewController(VC, animated: true)
}

Second View Controller 中执行此操作

class homeViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
}

func addObserver(){
    print("addObserverCalled")
    NotificationCenter.default.addObserver(self, selector: #selector(onNotification(notification:)), name: Notification.Name("myNotificationName"), object: nil)
}

@objc func onNotification(notification:Notification){
    print("NotificationCenter")
    print(notification.userInfo!)
}

}