Hai guys I am new to iOS development and still learning
I have a three View controllers ,viewController, SViewController, TViewController
in SviewController I have notification sender.post method on clicking a button
in viewController, TViewController viewdidload() methods I have .addobserver() methods
when I click a button on SViewController and post the notification
View Controller's selector is executed and not the TviewController
I have loaded the TviewController in FirstVC i.e ViewController viewdidload() method only
since segue performs again a viewdidload() from SviewController to TviewController with another button ,I tried to allocate a completion handler string to global variable so that it value remains same and print it(changed value) when view is loaded again, then I came to know that the completion handler is not at all executing here is the code
ViewController
import UIKit
extension Notification.Name{
static var fnote = Notification.Name("fnote")
}
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(fhandle(notification:)), name: .fnote, object: nil)
let storyboad = UIStoryboard(name: "Main", bundle: nil)
let tvc = storyboad.instantiateViewController(identifier: "1") as! TViewController
let _ = tvc.view
print(tvc.isViewLoaded)
print("journey")
}
@objc func fhandle(notification:Notification){
label.text = "Haii welcome to the hyderabad"
}
}
SViewController
import UIKit
var temp:String = "HHH"
class SViewController: UIViewController {
@IBAction func click(_ sender: Any) {
NotificationCenter.default.post(name: .fnote, object: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
TviewController
import UIKit
class TViewController: UIViewController {
@IBOutlet weak var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handler(notification:)) , name: .fnote, object: nil)
print(temp)
print("happy")
}
@objc func handler(notification:Notification)
{
print("jackson")
label2.text = "Hurray"
temp = label2.text ?? "Nothing"
}
}
Can Some one please help me with this
CodePudding user response:
let storyboad = UIStoryboard(name: "Main", bundle: nil)
let tvc = storyboad.instantiateViewController(identifier: "1") as! TViewController
let _ = tvc.view
print(tvc.isViewLoaded)
This is not the way to test the notification. Push your "TViewController" controller from the "ViewController" controller. Then post notification from your target controller.
CodePudding user response:
You haven't shown or explained where / when / how you're going to display the view from TViewController
, but to explain the first thing you're doing wrong...
In this code:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(fhandle(notification:)), name: .fnote, object: nil)
let storyboad = UIStoryboard(name: "Main", bundle: nil)
let tvc = storyboad.instantiateViewController(identifier: "1") as! TViewController
let _ = tvc.view
print(tvc.isViewLoaded)
print("journey")
}
as soon as viewDidLoad()
finishes (that is, immediately after the print("journey")
line), your tvc
instance of TViewController
is destroyed. That is, it's dumped from memory and no code inside it can execute, because it no longer exists.
That's called "going out of scope."
So, when you try to post a notification from SViewController
, there is no TViewController
in existence so its code is not running to "observe" the notification.
Here is a very simple example of multiple view controllers observing a notification:
When you push
from ViewController
to TViewController
, you get a new instance of TViewController
and the original instance of ViewController
still exists.
When you push
from TViewController
to SViewController
, you get a new instance of SViewController
and both ViewController
and TViewController
still exist.
When you tap the "Post" button, ViewController
and TViewController
will each execute the func you assigned to observe the notification.
When you then go Back to TViewController
, you'll see its label text has changed, and when you go back to ViewController
you'll see its label text has also changed.
Note that if you then push to TViewController
again, you get a new instance and its label will be back at its original text.
extension Notification.Name{
static var fnote = Notification.Name("fnote")
}
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(fhandle(notification:)), name: .fnote, object: nil)
print("journey")
}
@objc func fhandle(notification:Notification) {
print("Got it!")
label.text = "Haii welcome to the hyderabad"
}
}
class TViewController: UIViewController {
@IBOutlet weak var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handler(notification:)), name: .fnote, object: nil)
print("happy")
}
@objc func handler(notification:Notification) {
print("jackson")
label2.text = "Hurray"
}
}
class SViewController: UIViewController {
@IBOutlet var infoLabel: UILabel!
@IBAction func click(_ sender: Any) {
NotificationCenter.default.post(name: .fnote, object: nil)
infoLabel.text = "Notification Posted"
}
override func viewDidLoad() {
super.viewDidLoad()
}
}