Swift 3 NSNotificationCenter Keyboardwillshow/hide - ios

I have a piece of code that worked in Swift 2 and I tried using Xcode to update the code to the newest version and I fixed everything except two issues.
I have this code :
let loginvc: LoginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
NotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil)
NotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)
That pairs along with this:
func keyboardWillShow(notification: NSNotification) {
constraint.constant = -100
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
func keyboardWillHide(notification: NSNotification) {
constraint.constant = 25
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
On the first part I now get an error saying
Type 'LoginViewController' has no member 'keyboardWillShow/Hide'
I don't understand why it is not seeing the method underneath.
Does anybody know a solution to this issue?

Check out the updated Swift Programming Language book. Pages 1027 and 1028 are what you're looking for. It should be something like this:
func keyboardWillHide(_ notification: NSNotification) {…
Notice the additional underscore above. Also:
#selector(LoginViewController.keyboardWillHide(_:))
You also might need to add #objc(keyboardWillHideWithNotification:) to your class.

On Swift 4.2, addObserver name for NSNotificationCenter changed as well:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardDidShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardDidHideNotification, object: nil)

Use that code that's work on swift3
You can use your ViewController (e.g, loginvc) to add notification
let loginvc : LoginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
NotificationCenter.default.addObserver(self,
selector: #selector(loginvc.keyboardWillShow(notification:)),
name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(loginvc.keyboardWillHide(notification:)),
name: NSNotification.Name.UIKeyboardWillHide, object: nil)
Then add keyboard hide and show method
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
print("Show")
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
print("Hide")
}
}

NSNotificationCenter have things alter for get show keyboard:
NotificationCenter.default.addObserver(self, selector: #selector(NovaVisitaVC.abreTeclado(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(NovaVisitaVC.abreTeclado(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

Related

Problem with moving the view when the keyboard is open

I have a problem with the moving of text input and button when the keyboard is open. I am using the following code
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
#objc func keyboardWillChange(notification: NSNotification) {
guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
return
}
if notification.name == UIResponder.keyboardWillShowNotification || notification.name == UIResponder.keyboardWillChangeFrameNotification {
view.frame.origin.y = -keyboardSize.height
} else {
view.frame.origin.y = 0
}
}
The problem occurs when I start typing in the text field, here are images before: https://imgur.com/a/cbQbJzW and after: https://imgur.com/a/f1Nakrs
I am sorry about the language it of files don't say anything spacial.
I want to know why this happens, is it possible to be because I am using CocoaPods - YoshikoTextField in the grey text field ?
Thank you!
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var backgroundScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
// Do any additional setup after loading the view, typically from a nib.
}
#objc func keyboardWillShow(notification:NSNotification) {
adjustingHeight(true, notification: notification)
}
#objc func keyboardWillHide(notification:NSNotification) {
adjustingHeight(false, notification: notification)
}
func adjustingHeight(_ isShow:Bool, notification:NSNotification) {
let userInfo = notification.userInfo!
let keyboardFrame = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let changeInHeight = (keyboardFrame.height + 20) * (isShow ? 1 : -1)
backgroundScrollView.contentInset.bottom += changeInHeight
backgroundScrollView.scrollIndicatorInsets.bottom += changeInHeight
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Modal UIViewController can't receive NSNotifications

I have a modal UIViewController:
let rVC = RecoveryViewController()
rVC.modalPresentationStyle = .overFullScreen
self.present(rVC, animated: true, completion: nil)
In viewDownload of this ViewController I have a function user.checkUserData() that would send NSNotifications when the job is done.
And, of course, observers for any of these notifications:
NotificationCenter.default.addObserver(self, selector: #selector(RecoveryViewController.userVIP), name: userDataIsHere, object: nil)
But it seems that my modal ViewController is not able to receive any notifications, because nothing is happening. At the same time if I tried to add such observer to the parent UIViewController (non-modal), it'd work like a charm (actually, I checked).
My notifications are quite simple, and
let userDataIsHere = Notification.Name("userDataIsHere")
NotificationCenter.default.post(name: userDataIsHere, object: nil)
What am I doing wrong here?
Try this.
class ViewController: UIViewController {
let userDataIsHere = Notification.Name("userDataIsHere")
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(modalPopUp), name: userDataIsHere, object: nil)
}
#objc func modalPopUp() {
let rVC = RecoveryViewController()
rVC.modalPresentationStyle = .overFullScreen
self.present(rVC, animated: true, completion: nil)
}
}
Make sure you completed below things:
1) Notification Registered before use
2) Notification identifier must be same.
Here is my code for notification:
1) Registered Notification in viewDidLoad:
let notificationName = Notification.Name("NotificationIdentifier")
NotificationCenter.default.addObserver(self, selector: #selector(yourFunctionName), name: notificationName, object: nil)
#objc func yourFunctionName(notification: NSNotification){
//do stuff
print("Called..")
}
2) Post notification when you required:
// Post notification
let notificationName = Notification.Name("NotificationIdentifier")
NotificationCenter.default.post(name: notificationName, object: nil)

Change UIScrollView Offset to top from another viewController in Swift 4

I have mainViewController and inside have scrollView and I have secondViewController I want to change scrollView offset to top from secondViewController when I want to try it with NSNotificationCenter gives me ;
: unrecognized selector sent to instance 0x7ff83e024200'
How can I fix it ?
My codes under below.
mainViewController
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: "gotop:", name: NSNotification.Name(rawValue: "gotop"), object: nil)
}
func gotop(){
scrollView.setContentOffset(CGPoint(x:0, y:0), animated: false)
}
secondViewController
#IBAction func goButton (sender : UIButton){
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "gotop"), object: nil)
}
check your addObserver code, selector should have below signature
NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.goTop(notification:)), name: Notification.Name("gotop"), object: nil)
Method handler for received Notification:
func goTop(notification: Notification){
scrollView.setContentOffset(CGPoint(x:0, y:0), animated: false)
}
For posting notification
NotificationCenter.default.post(name: Notification.Name("gotop"), object: nil)
Remove Notification in denit
deinit {
NotificationCenter.default.removeObserver((self, name: Notification.Name("gotop"), object: nil)
}
I have used below code in my project to add notification :
NotificationCenter.default.addObserver(self, selector: #selector(YourViewController.gotop), name: NSNotification.Name(rawValue: "gotop"), object: nil)
Try if it works in your scenario.
the definition of your "goTop" func is wrong :
instead of
func gotop(){
//do your stuff
}
try this :
func gotop(notification : NSNotification){
//do your stuff
}
let me know if this solve your problem.

NotificationCenter is not calling the selector

I've searched about this but the problem still exist for me. I found this great question but unfortunately it didn't work for me. This is the first time I'm working with NotificationCenter and the need to use this first occurs when I wanted to pass data to a viewcontroller under a tab of XLPagerTabStrip.
So here is how I am posting the Notification:
if let doc_ID = mainDoctorsArray[sender.tag].doctors_id {
NotificationCenter.default.post(name: Notification.Name("docID"), object: nil, userInfo: ["value" : doc_ID])
}
In the class I've made for observing this notification I'm calling NotificationCenter.default.addObserver(self, selector: #selector(gotDocID), name: Notification.Name("docID"), object: nil)
The selector method is:
func gotDocID(notification:NSNotification) {
let userInfo:Dictionary<String,String> = notification.userInfo as! Dictionary<String,String>
if let item = userInfo["value"] {
getDoctorDetails(docID: Int(item)!)
//print(item,self)
}
}
I've also tried adding observer as:
NotificationCenter.default.addObserver(self, selector: #selector(AvailableViewController.gotDocID(notification:)), name: Notification.Name("docID"), object: nil) but still same result.
The issue is that func gotDocID(notification:NSNotification) is not being called.
UPDATE
Class which is posting the notification is ViewController.swift and the class which has the observer is AvailableViewController.swift
Based on a comment I've changed observer to NotificationCenter.default.addObserver(self, selector: #selector(AvailableViewController.gotDocID(notific‌​ation:)), name: Notification.Name("NotificationIdentifier"), object: nil) and this error is generated.
and also by doing the follow I'm getting the same error.
Value of type 'AvailableViewController' has no member 'gotDocID'
You can use the below code to post and get data.
//Post notification
NSNotificationCenter.defaultCenter().postNotificationName("docID", object: nil, userInfo: ["value" : doc_ID])
//Get data from observer
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AvailableViewController.gotDocID(_:)), name: "docID", object: nil)
//Method called after notification is posted.
func gotDocID(notification: NSNotification) {
if let image = notification.userInfo?["value"] as? String {
// do something with your data
}
}
Please check :
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.gotDocID(notification:)), name: Notification.Name("docID"), object: nil)
}
#IBAction func saveButton(_ sender: UIButton) {
NotificationCenter.default.post(name: Notification.Name("docID"), object: nil, userInfo: ["value" : "123"])
}
#objc func gotDocID(notification:NSNotification) {
let userInfo:[String: String] = notification.userInfo as! [String: String]
if let item = userInfo["value"] {
print(item,self)
}
}
}
Add #objc to your function
#objc func gotDocID(notification:NSNotification) {
}
// Define identifier
let notificationName = Notification.Name("docID")
// Register to receive notification
NotificationCenter.default.addObserver(self, selector: #selector(AvailableViewController.gotDocID(notification:)), name: notificationName, object: nil)
// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)
// Stop listening notification
NotificationCenter.default.removeObserver(self, name: notificationName, object: nil);
Why dont you try closure
Make sure your post notification occures.
Change
NotificationCenter.default.post(name: Notification.Name("docID") , object: ["value" : doc_ID])
NotificationCenter.default.addObserver(forName: Notification.Name("docID"), object: nil, queue: OperationQueue.main) { (notify) in
print(notify.object as! Dictionary<String,String>)
}

NSNotfication.addObserver - Update to current Swift Syntax?

Currently following a tutorial, however, some of the syntax is outdated. Basically the code should show and hide the user keyboard. I get some syntax errors with the addObserver method and Swift wants me to use key path instead, however, if i use the auto 'fix-it' i get even more errors. Can anyone help me out with this? Thanks!
NSNotification.addObserver(self, selector: #selector(keyboardwillShow), name: .UIKeyboardWillShow, nil)
NSNotification.addObserver(self, selector: #selector(keyboardwillHide), name: .UIKeyboardWillHide, nil)
func keyboardwillShow(_notification:NSNotification) {
keyboard = (_notification.userInfo![UIKeyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue
UIView.animate(withDuration: 0.4) {
self.scrolledView.frame.size.height = self.scrollViewHeight - self.keyboard.height
}
}
func keyboardwillHide(_notification:NSNotification) {
UIView.animate(withDuration: 0.5) {
self.scrolledView.frame.size.height = self.view.frame.height
}
}
I get the debug message: "Incorrect argument labels in call(have _selector:name, expected _forKeyPath:options:context"
Your function has argument, That is missing when you add it in observer
And you have to use NotificationCenter.default.addObserver not NotificationCenter.addObserver
let selectorForKeyBoardWillShow: Selector = #selector(ViewController.keyboardWillShow(_:))
let selectorForKeyBoardWillHide: Selector = #selector(ViewController.keyboardWillHide(_:))
// MARK: - Functions
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: selectorForKeyBoardWillShow, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: selectorForKeyBoardWillHide, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
// MARK: Keyboard Observer
func keyboardWillShow(_ notification: Notification) {
}
func keyboardWillHide(_ notification: Notification) {
}

Resources