1

I want to pass ina second parameter to a selector function that comes from another function:

func bindToKeyboardNew(constraint: NSLayoutConstraint) { // <- this parameter 
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:constraint:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWillShow(_ notification: NSNotification, constraint: NSLayoutConstraint) // <- To This selector {

}
5
  • 1
    You can't. You need another way to access the constraint in the keyboardWillShow function. Commented Mar 28, 2019 at 2:45
  • What is the workaround there? I'm trying to develop an extension to bind a view to keyboard very easily ;( Commented Mar 28, 2019 at 2:50
  • 1
    you can bind view in userInfo dict in notification of selector Commented Mar 28, 2019 at 4:35
  • @abu ul Hassan it's like normal binding, it doesn't work properly Commented Mar 28, 2019 at 6:49
  • well it should work properly, matter is sending an object with valid approach and i think there is no more valid way to pass any object except userInfo dict. Commented Mar 28, 2019 at 6:51

2 Answers 2

3

The easier way you can pass data is creating a custom class. Example I need pass data through UITapGestureRecognizer.

First, create a custom UITapGestureRecognizer and define a instance which is your data

class CustomTapGesture: UITapGestureRecognizer {
    var data: YourData
}
let tapGesture = CustomTapGesture(target: self, action: #selector(tapGesture(_:)))
tapGesture.data = yourData
yourView.addGestureRecognizer(tapGesture)

#selector function

@objc func tap(_ sender: UITapGestureRecognizer) {
    if let sender = sender as? CustomTapGesture {
       yourData = sender.data
       // do something with your data
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I understand but what is it in my case with NotificattionCenter and NSNotification they're two different Things
U can create a custom class and instance of NotificattionCenter and NSNotification are your data.
class Custom { var instance1: NotificattionCenter? var instance2: NSNotification? }
0

As @rmaddy mentioned in the comment this cannot be done the way you're asking for.

In this part

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:constraint:)), name: UIResponder.keyboardWillShowNotification, object: nil)

you have no control over how exactly the selector is sent (and with what args).

UIKit internally in its private implementation does something like this (let's ignore for a second that its implementation isn't really Swift, that's not important here):

NotificationCenter.default.post(name: NSNotification.Name(rawValue: UIResponder.keyboardWillShowNotification), object: uiwindow, userInfo: systemUserInfoForKeyboardShow)

What it means the selector is already sent and there's no way to add something extra to optional userInfo (you could do that if the .post(...) did happen in your code, but that's not the case here).

You need an alternative way to access your current NSLayoutConstraint object inside the keyboard selector show/hide handlers. Maybe it should be a property in your ViewController , maybe some state of your AppDelegate or maybe something completely different, it's impossible to tell not knowing rest of your code.

EDIT: As per your added comment I'd assume that you have something like this:

class ViewController: UIViewController {
    @IBOutlet var constraint: NSLayoutConstraint?
}

If so you can simply access the constraint in your selector handler inside the VC:

class ViewController: UIViewController {
    @IBOutlet var constraint: NSLayoutConstraint?
    @objc func keyboardWillShow(_ notification: NSNotification) {
       //do something with the constraint 
       print(constraint)
    }
}

There's also a dedicated UIKeyboardWillChangeFrameNotification perhaps it could provide you with what you need out of the box. See the answer here

2 Comments

Its in my Viewcontroller
I know what. But That's not what I want. I wanted a dedicated class for that so I don't have to put that chunk of code in it. But I found a solution already(look at my other question). Thanks anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.