How to create Selector with parameters from string

12,075

Solution 1

Here is what you want, Selector with string type and Notification parameter argument

Swift 4

NotificationCenter.default.addObserver(self, selector: Selector(("showKeyboard:")), name:NSNotification.Name.UIKeyboardWillShow, object: nil)

var keyboardHeight = 0.0
//-------------------
@objc func showKeyboard(_ sender: Notification) {
    keyboardWillShow(sender: sender as NSNotification, adjustHeight: 150)
    print("sender - \(sender)")
}

//-------------------
func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        keyboardHeight = Double(keyboardSize.height)
        // do your calculations
    }
}


Swift 3

NotificationCenter.default.addObserver(view, selector: Selector(("keyboardWillShow:")), name: .UIKeyboardWillShow, object: anyView.view.window)

func keyboardWillShow(_ notification: Notification) { 
       keyboardWillShow(sender: sender as NSNotification, adjustHeight: 150)
        print("sender - \(sender)")

} 



Here are normal selector, according to language support
Swift 4

NotificationCenter.default.addObserver(self, selector: #selector(self.showKeyboard(sender:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)

var keyboardHeight = 0.0

    //-------------------
    @objc func showKeyboard(sender: NSNotification) {
        keyboardWillShow(sender: sender, adjustHeight: 150)
    }

    //-------------------
    func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
        if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            keyboardHeight = Double(keyboardSize.height)
            // your operations here
        }
    }


Swift 3

NotificationCenter.default.addObserver(self, selector: #selector(self.showKeyboard(sender:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)

var keyboardHeight = 0.0

    //-------------------
    func showKeyboard(sender: NSNotification) {
        keyboardWillShow(sender: sender, adjustHeight: 150)
    }

   //-------------------
    func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
        if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            keyboardHeight = Double(keyboardSize.height)
            // your operations here
        }
    }

Solution 2

This way works,

override func viewDidLoad() {
    super.viewDidLoad()
// put it wherever you want
 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showKeyboard), name:UIKeyboardWillShowNotification, object: nil)
}

func showKeyboard(sender: NSNotification) {
    keyboardWillShow(sender, adjustHeight: 150)
}

func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
        keyboardHeight = keyboardSize.height
 // do your calculations
    }
}

This will helps you to achieve your expected result.

Share:
12,075

Related videos on Youtube

Alex
Author by

Alex

I am looking for Backend development job. Please, look at my CV in JSON format: https://rutracker.tech/cv

Updated on June 04, 2022

Comments

  • Alex
    Alex almost 2 years

    I am writing a program using Swift 3.1 and Xcode 8.3.3. I want to create a class, responsible for moving entire view when keyboard appears and disappears. But I faced difficulties with creating custom Selector with parameters from string. To show or hide keyboard we need function:

    func keyboardWillShow(notification: Notification) {
    //Code moving view when keyboard appears
    }
    

    I am trying to create a selector like this:

    let selector = Selector(("keyboardWillShow")
    NotificationCenter.default.addObserver(view, selector: selector, name: .UIKeyboardWillShow, object: anyView.view.window)
    

    It is compiling, but when keyboard appears, it crashes. Because it is independent class I cannot use this construction:

    #selector(keyboardWillShow)
    

    Because it transforms Swift function to Objective-C function (adding @objc). So question is: how to create a Selector form with parameters string?

    P. S. I can put the whole code there but I don't want question to be very big, so I will edit question if somebody asks...

  • Alex
    Alex almost 7 years
    Yes, this works, but main idead to avoid writing this NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name:UIKeyboardWillShowNotification, object: nil) and the same long line for hiding keyboard in ViewDidLoad.
  • Praveen Kumar
    Praveen Kumar almost 7 years
    This is the generic approach whenever the keyboard appears or disappears, the selector method gets called. So what is your expectation?!
  • Alex
    Alex almost 7 years
    I want to write a class, general class. So, idea is to avoid of duplicate of long code. I can do yours approach on each view, but I want to avoid of doing it.
  • Praveen Kumar
    Praveen Kumar almost 7 years
    you can write keyboardWillShow in a base class and inherit it to the other classes to access the method but you have to use NSNotificationCenter at whichever class you need.
  • Alex
    Alex almost 7 years
    It seems only one way now... Thank you. But still, parameters are not available in selectors?
  • Alex
    Alex almost 7 years
    Thank you for idea but I doubt that I should do like this. There is much more better way to calculate height of keyboard...
  • Praveen Kumar
    Praveen Kumar almost 7 years
    This is how you can get the let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() vaue. you can get the height and width like this keyboardSize.height and keyboardSize.width.
  • Alex
    Alex almost 7 years
    Yes, I know how to move keyboard. Problem is I do not know how to add observer with specific selector. But your idea to make a class and inherit from it looks very good.
  • Praveen Kumar
    Praveen Kumar almost 7 years
    You can add the observer code wherever you want but the viewDidLoad will be the apt one. And the selector can be any method name you write. Try it. If my answer works mark it as accepted answer. Thanks!
  • Alex
    Alex almost 7 years
    Thank you for your answer, but it is not quite the same. Question is how to create selector with parameters from string. Moreover, even in swift 3.1 you should not use NS functions or variables without special need. Download my project please and see how not to use NSValue.
  • Alex
    Alex almost 7 years
    But please, can I make some more comments?
  • Alex
    Alex almost 7 years
    First, remove @objc , it causes warning. Second: I think we do not need two functions: showKeyboard and keyboardWillShow. We can easily unite them in one. In fact the most useful part is this: showKeyboard(_ sender: Notification) This symbol "_" I was looking for! Thank you!!!
  • Alex
    Alex almost 7 years
    I do not know how to edit other answers but it does not matter, it is working! Other people will see it too. Thank You very much again!!!
  • Krunal
    Krunal almost 7 years
    Please paste your code here in comment area.. as qualitative question and answer are useful rather than simple statements.
  • Alex
    Alex almost 7 years
    NotificationCenter.default.addObserver(view, selector: Selector(("keyboardWillShow:")), name: .UIKeyboardWillShow, object: anyView.view.window)
  • Alex
    Alex almost 7 years
    func keyboardWillShow(_ notification: Notification) { //... }
  • Alex
    Alex almost 7 years
    But screen, where you calling this also must have func keyboardWillShow(_ notification: Notification) { //... } It is important!
  • filip.karas
    filip.karas over 5 years
    Why are you using double parentheses around the function name?