Reputation:
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 {
}
Upvotes: 1
Views: 2084
Reputation: 5543
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
Upvotes: 0
Reputation: 188
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
}
}
Upvotes: 3