How do I use #selector? [duplicate] - ios

This question already has answers here:
How do I resolve "ambiguous use of" compile error with Swift #selector syntax?
(3 answers)
Closed 6 years ago.
How do I convert these statements to use the #selector statement.
The statements work fine but gives warnings in Xcode, which I dislike.
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)

In Swift 3, it looks like this:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

Related

Type of expression is ambiguous without more context: .UIApplication.willResignActiveNotification

I am getting
Type of expression is ambiguous without more context
on the following lines:
NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: .UIApplication.willResignActiveNotification , object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(openedAgain), name: .UIApplication.didBecomeActiveNotification, object: nil)
What is the correct syntax?
remove the . on UIApplication.willResignActiveNotification.
Your line should look like this:
NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification , object: nil)

Moving UITextField up with keyboard - changes in swift 4.2?

I had this function to move certain textfields upwards, when the keyboards would block their view - I'm sure you all know about this:
override func viewDidLoad() {
super.viewDidLoad()
let center: NotificationCenter = NotificationCenter.default
center.addObserver(self, selector: #selector(keyboardDidShow(notification:)), name: NSNotification.Name?.UIKeyboardDidShow, object: nil)
center.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name?.UIKeyboardWillHide, object: nil)
}
But when I recently updated to swift 4.2, these stopped working, and these suggestions came up:
Replace 'UIKeyboardDidShow' with 'UIResponder.keyboardDidShowNotification' &
Replace 'UIKeyboardWillHide' with 'UIResponder.keyboardWillHideNotification
But when I pressed "fix", I get the error (x2):
Type 'NSNotification.Name' has no member 'UIResponder'
It kind of seems like a bug to me? That xCode can't accept it's own changes?? Anybody came across this and knows what to do?
Thanks!
Try this
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification object: nil)
More info use this link :- enter link description here
I hope this will help you :D
Thanks

How to restrict NSNotification to call methods multiple times in iOS?

I am using NSNotificationCenter to send local notifications in my code and working in both Objective-C and Swift. I'm posting notifications from Objective-C And receiving in Swift. But the methods that I added in notification getting called multiple times and added observer only in viewDidLoad method.
Swift:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.serverCardSynced), name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.checkForAutoSync), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateSync), name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object:nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.menuRemoved), name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object:nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.reloadAllCards(_:)), name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object:nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateDownloadMyCards), name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object:nil);
}
Objective-C:
- (void)applicationDidBecomeActive:(UIApplication *)application {
self.isSyncPending = true;
[[NSNotificationCenter defaultCenter]
postNotificationName:NOTIF_CONTACT_ENTITY_CHANGE object:nil];
}
-(void)insertData(){
[[NSNotificationCenter defaultCenter]
postNotificationName:NOTIF_SERVER_CARD_SYNCED object:nil];
}
I added remove observer in my deinit but it is not even calling. How to stop calling multiple times.
//call this method in viewDidLoad
fileprivate func registerNotifs() {
//remove observer before adding to make sure that it is added only once
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.serverCardSynced), name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.checkForAutoSync), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateSync), name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object:nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.menuRemoved), name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object:nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.reloadAllCards(_:)), name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object:nil);
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateDownloadMyCards), name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object:nil);
}
you can do like this
fileprivate func registerLocalNotifications() {
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.serverCardSynced), name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.checkForAutoSync), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateSync), name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object:nil)
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.menuRemoved), name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object:nil)
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.reloadAllCards(_:)), name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object:nil)
NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateDownloadMyCards), name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object:nil)
}
add above method in viewDidLoad and in
deinit {
NotificationCenter.default.removeObserver(self)
}
REF : Where to remove observer for NSNotification in Swift?
Update:
Check you class instance if it already persist i.e
in view when you are instantiating this view controller
you can do like this
if let vc = yourNotificationViewCointrollerObj {
// USE EXISTING ONE
} else {
// CREATE NEW INSTANCE
}
NSNotificationCenter is a "publish-subscribe" mechanism where each posted notification is delivered to all subscribers (called observers). If you receive a notification multiple times it means that either you have multiple subscribers, or you are sending a notification multiple times.
I assume that you have only one subscriber for each notification type - your MainScreen UIViewController in Swift. It means that you probably send each notification multiple times.
For example applicationDidBecomeActive is called multiple times (each time the app becomes active). If you want to stop responding to this notification after the first time, you could unsubscribe from it as soon as you receive it first time:
#objc
func initateSync {
// do something first time
// ...
// unsubscribe to not receive it anymore
NotificationCenter.default.removeObserver(self,
name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE),
object: nil)
}
This is what you do in real world after receiving a newspaper trial that you didn't like :)

Using selector in Swift 3 NotificationCenter observer

NotificationCenter.default.addObserver(self, selector: Selector(("uploaded")), name: NSNotification.Name(rawValue: "uploaded"), object: nil)
I was writing name: "uploaded:" and xcode corrected it to the above code. The problem is when running the app i get unrecognized selector.
Any one know how to fix this to work with swift 3
Use the (identifier checking) #selector syntax:
Without parameter:
#selector(uploaded)
With parameter:
#selector(uploaded(_:))
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.update), name: NSNotification.Name(rawValue: "uploaded"), object: nil)
func update() {
// do what you want
}
please note that "ViewController" is the class name where your function is

Segmentation fault: 11; (xcode 8, Swift 3) after using NotificationCenter

Getting Segmentation fault in Xcode 8
I have recently migrated my project to Swift 3. Xcode Version 8.0 (8A218a)
I get this error whenever I use UIKeyboardWillShow notification :
Command failed due to signal: Segmentation fault: 11`
This is how I am using the notification in my code:
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.removeObserver(NSNotification.Name.UIKeyboardWillShow)
NotificationCenter.default.removeObserver(NSNotification.Name.UIKeyboardWillHide)
NotificationCenter.default.addObserver(self, selector: #selector(myViewController.keyboardWillShow(_:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(myViewController.keyboardWillHide(_:)), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWillShow(_ sender: Notification) {
//keyboardWillShow Method
}
func keyboardWillHide(_ sender: Notification) {
// keyboardWillHide Method
}
Project runs successfully when I comment out the code in viewWillAppear method.
The main topic: Segmentation fault: 11, it's a bug of Xcode8/Swift3 and you should send a bug report.
And about your code:
NotificationCenter.default.removeObserver(NSNotification.Name.UIKeyboardWillShow)
NotificationCenter.default.removeObserver(NSNotification.Name.UIKeyboardWillHide)
There are no methods removing observers specifying only their names. You need to specify observer object for removeObserver(_:).
I'm not sure this is what you intend, but you can use removeObserver(_:name:object:) method like this:
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
I'm sure this would not crash your Xcode.
I had the same issue in the same conditions and environment (Swift 3, Xcode 8) and to resolve this problem you should put:
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
instead of:
NotificationCenter.default.removeObserver(NSNotification.Name.UIKeyboardWillShow)
NotificationCenter.default.removeObserver(NSNotification.Name.UIKeyboardWillHide)

Resources