繁体   English   中英

NotificationCenter 在从视图控制器发布到另一个视图控制器时第一次不工作

[英]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)
}

}

实际 Output

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

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

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

而是删除通知并根据您的需要从 ViewController2 Viewdidload/ViewWillappear/Viewdidappear 调用 print1Method。 如果要将一些数据从 ViewController1 传递到 ViewController2,请在 ViewController2 中保留一些公共变量并在 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)
}

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

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

第一个视图中Controller 在您的按钮单击中添加此 function

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

第二个视图中 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!)
}

}

您在视图 controller 初始化之前发布通知。

调用vc2的方法无需发布通知。 而是直接调用该方法。

在 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")
 }

同样对于后退按钮,您做错了。 只需从堆栈中弹出视图 controller

 @IBAction func backToVC1(_ sender: Any) {

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

暂无
暂无

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

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