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 {

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 1
    You can't. You need another way to access the constraint in the `keyboardWillShow` function. – rmaddy Mar 28 '19 at 02:45
  • What is the workaround there? I'm trying to develop an extension to bind a view to keyboard very easily ;( –  Mar 28 '19 at 02:50
  • 1
    you can bind view in userInfo dict in notification of selector – Abu Ul Hassan Mar 28 '19 at 04:35
  • @abu ul Hassan it's like normal binding, it doesn't work properly –  Mar 28 '19 at 06: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. – Abu Ul Hassan Mar 28 '19 at 06:51

2 Answers2

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
    }
}
Dimple
  • 788
  • 1
  • 11
  • 27
T.Nhan
  • 188
  • 1
  • 9
  • I understand but what is it in my case with NotificattionCenter and NSNotification they're two different Things –  Mar 28 '19 at 13:10
  • U can create a custom class and instance of `NotificattionCenter` and `NSNotification` are your data. – T.Nhan Mar 29 '19 at 04:48
  • ```class Custom { var instance1: NotificattionCenter? var instance2: NSNotification? }``` – T.Nhan Mar 29 '19 at 04:54
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

Kamil.S
  • 5,205
  • 2
  • 22
  • 51
  • Its in my Viewcontroller –  Mar 29 '19 at 16:11
  • 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. –  Mar 30 '19 at 22:34