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!)
}
}
我有 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!)
}
}