notification center observer to check an NSTextView wont work right - swift

I'm using a notification center observer to check an NSTextView
NotificationCenter.default.addObserver(self, selector: #selector(testest), name: NSTextView.didEndEditingNotification, object: nil)
it works but the thing is, i got two nstextview and it automaticly picks up on one
even when i specify its name in obejct?? why is that?
like this
NotificationCenter.default.addObserver(self, selector: #selector(testest), name: NSTextView.didEndEditingNotification, object: BoxText)
Update: It acutlay picks up on both of my NSTextViews how do i specify one?

If you pass nil all NSTextView in your view controller will receive the notification. Just create an IBOutlet to each NSTextView, cast the notification object to NSTextView and check if it is equal to each of them. If you would like to have a selector to fire just for a certain text view you need to pass it as the object parameter:
import Cocoa
class ViewController: NSViewController {
#IBOutlet var textViewLeft: NSTextView!
#IBOutlet var textViewRight: NSTextView!
override func viewDidLoad() {
super.viewDidLoad()
// If you pass nil all NSTextView in your view controller will receive the notification
NotificationCenter.default.addObserver(self, selector: #selector(didEndEditing), name: NSTextView.didEndEditingNotification, object: nil)
// If you would like to have a selector to fire just for a certain text view you need to pass it as the object parameter
NotificationCenter.default.addObserver(self, selector: #selector(didEndEditingTextViewLeft), name: NSTextView.didEndEditingNotification, object: textViewLeft)
NotificationCenter.default.addObserver(self, selector: #selector(didEndEditingTextViewRight), name: NSTextView.didEndEditingNotification, object: textViewRight)
}
#objc func didEndEditing(_ obj: Notification) {
if (obj.object as? NSTextView) == textViewLeft {
print(#function, "textViewLeft")
} else if (obj.object as? NSTextView) == textViewRight {
print(#function,"textViewRight")
}
}
#objc func didEndEditingTextViewLeft(_ obj: Notification) {
print(#function)
}
#objc func didEndEditingTextViewRight(_ obj: Notification) {
print(#function)
}
}

Related

How to send a notification from UIKit to a view in SwiftUI?

I am trying to send a notification from UIViewcontroller to SwiftUI View after the user did pull to refresh.
#objc private func fetchScheduleData(_ sender: UIRefreshControl) {
NotificationCenter.default.post(name: Notification.Name(rawValue: "didPullToRefreash"), object: nil)
}
On SwiftUI view i trying to set this method .onchange()
NotificationCenter.default.addObserver(self, selector: #selector(didPullToRefreashHelper), name: Notification.Name(rawValue: "didTapNotification"), object: nil)
But onChange it's not working. I am wondering i how i will do this.
The simplest way of doing this would be to first, create the custom notification like this:
extension Notification.Name {
static let didPullToRefresh = Notification.Name("didPullToRefresh")
}
That now lets you address it with dot notation. Next, in your VC:
#objc private func fetchScheduleData(_ sender: UIRefreshControl) {
NotificationCenter.default.post(name: .didPullToRefresh, object: nil)
}
Lastly, in your SwiftUI view:
.onReceive(NotificationCenter.default.publisher(for: .didPullToRefresh)) { _ in
// If you are passing an object, this can be "notification in"
// Do something here as a result of the notification
}
edit:
If you want to send a message in a SwiftUI view when a variable changed, then you could use .onChange(of:) like this:
.onChange(of: watchedStateVar) { value in
NotificationCenter.default.post(name: .didPullToRefresh, object: value)
}

Swift NSNotification Observers not working

I have 2 view controllers, one with a switch that when toggled should post the following notification. In the other view controller I have Observers which should trigger the following function which just toggles a boolean. I am not able to get the observers to work and make that function call, am I doing something wrong here? I have another Notification (Doesn't trigger with user input) that is being sent in the opposite direction which works fine.
#IBAction func switchAction(_ sender: Any) {
if switchUI.isOn {
print("Collecting Data ")
NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Collect"), object: self)
}
else
{
print("Not Collecting Data")
NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Do Not Collect"), object: self)
}
}
func collectDataObserver () {
//Add an Observer
NotificationCenter.default.addObserver(self, selector: #selector(CentralViewController.toggleData(notification:)), name: Notification.Name(rawValue: "Collect"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(CentralViewController.toggleData(notification:)), name: Notification.Name(rawValue: "Do Not Collect"), object: nil)
}
#objc func toggleData(notification: NSNotification) {
let isCollectData = notification.name.rawValue == "Collect"
if(isCollectData){
IsCollectingData = true
}
else
{
IsCollectingData = false
}
}
You need to call collectDataObserver() in viewDidLoad() of CentralViewController, i.e.
override func viewDidLoad() {
super.viewDidLoad()
collectDataObserver()
}

What is the best way of updating a variable in a view controller from scene delegate?

I am using Spotify SDK. I want to change labels in some view controllers when a user changes his/her player state. Here is my scene delegate:
var playerViewController = MatchViewController()
func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
playerViewController.stateChanged(playerState)
}
A view controller:
func stateChanged(_ playerState: SPTAppRemotePlayerState) {
// aLabel.text = playerState.track.name
}
The problem is labels or other outlets are nil when the state is changed because the view controllers are not loaded at that time. How can I fix that? (I tried isViewLoaded)
If you have a more than a few places to update according to a change that occurs at one place use observers. Here's how,
Post notification in SceneDelegate like this:
func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "stateChanged"), object: nil, userInfo: ["playerState": playerState])
}
Observe in ViewControllers like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(stateChanged), name: NSNotification.Name("stateChanged"), object: nil)
}
#objc func stateChanged(_ notification: Notification) {
if let playerState = notification.userInfo?["playerState"] as? SPTAppRemotePlayerState {
print(playerState)
}
}
}

How to detect day change in Swift

I want my app to act when there is a change to another day.
So, in my appDelegate, I put
func applicationSignificantTimeChange(_ application: UIApplication){
//this one fires
}
and in the ViewController that should update its content I do:
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(self.dayChanged(notification:)), name: Notification.Name("significantTimeChangeNotification"), object: nil)
}
and
#objc func dayChanged(notification: NSNotification){
//this one doesn't fire
}
somehow, while the func in AppDelegate is called, the observer seems to be blind for that event.
Is this syntax, or just plain misunderstanding of the mechanism?
You need to add an observer for "UIApplicationSignificantTimeChangeNotification":
NotificationCenter.default.addObserver(self, selector: #selector(dayChanged), name: UIApplicationSignificantTimeChangeNotification, object: nil)
For Swift 4.2 or later
NotificationCenter.default.addObserver(self, selector: #selector(dayChanged), name: UIApplication.significantTimeChangeNotification, object: nil)
Note: If your intent is to be notified when the day changes you can use .NSCalendarDayChanged ("NSCalendarDayChangedNotification") instead of UIApplication.significantTimeChangeNotification.
NotificationCenter.default.addObserver(self, selector: #selector(dayChanged), name: .NSCalendarDayChanged, object: nil)
And add the selector method to the view controller where you would like to monitor the day changes:
#objc func dayChanged(_ notification: Notification) {
}

NsNotificationCenter is not working

Actually i'm new in swift i got stuck here,Anyone can solve this Problem. actOnSpecialNotification Func is not calling on fireNotification in ViewController.swift
In ViewController.swift
func fireNotification() -> Void {
NotificationCenter.default.addObserver(self, selector:
#selector(vikas.updateNotificationSentLabel), name:
NSNotification.Name(rawValue: mySpecialNotificationKey), object: nil)
}
func updateNotificationSentLabel() {
print("sent")
}
in SecondVC.swift
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector:
#selector(ViewController.actOnSpecialNotification), name:
NSNotification.Name(rawValue: mySpecialNotificationKey), object: nil)
}
func actOnSpecialNotification() {
print("listen")
}
First of all add Observer to your FirstViewConroller.
FirstViewConroller
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:”test”, object: nil)
Now, add the relevant selector method in same ViewController which will be called once the notification will be fired.
func methodOfReceivedNotification(notification: Notification){
//Take Action on Notification
}
Now, you can fire the notification using below lines which will call the above method which resides in FirstViewController
SecondViewController
NSNotificationCenter.defaultCenter().postNotificationName(“test”, object: nil)