1
votes

I have set up a gesture recognizer for dismissing the keyboard when the user taps outside the textfield. DismissKeyboard function does not get called.

Have I set up the observer wrong or is this a different issue? Also, this is a tableview that is being tapped.

Code Excerpt

class CommentsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: Selector("keyboardWillShow:"),
            name: UIKeyboardWillShowNotification,
            object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: Selector("keyboardWillHide:"),
            name: UIKeyboardWillHideNotification,
            object: nil)
    }

    func keyboardFrameChanged(notification: NSNotification) {
        println("keyboardFrameChanged")
        let userInfo = notification.userInfo
        let key = UIKeyboardFrameEndUserInfoKey
        if let info = userInfo {
            let frameValue = info[key] as! NSValue
            let _frame = frameValue.CGRectValue()
        }
    }
    
    func keyboardWillShow(notification: NSNotification) {
        if keyboardDismissTapGesture == nil
        {
            println("dismiss")
            keyboardDismissTapGesture = UITapGestureRecognizer(target: self, action: Selector("dismissKeyboard:"))
            self.view.addGestureRecognizer(keyboardDismissTapGesture!)
        }
    }
    
    func keyboardWillHide(notification: NSNotification) {
        if keyboardDismissTapGesture != nil
        {
            println("test2")
            self.view.removeGestureRecognizer(keyboardDismissTapGesture!)
            keyboardDismissTapGesture = nil
        }
    }
    
    func dismissKeyboard(sender: AnyObject) {
        println("dismiss keyboard")
        commentTextField.resignFirstResponder()
    }

I set a breakpoint at dismissKeyboard, but it doesn't even get called.

Output

When I tap the textview and the keyboard opens, this is the output

keyboardFrameChanged
keyboardFrameChanged
will show
dismiss

When I tap anything else (trying to dismiss the keyboard), no further outputs.

1
Are the notifications for the keyboard showing and hiding being called? - chedabob
Instead of Breakpoints I would consider placing some println() statements and then see how far it gets. Can you do that for us? - LinusGeffarth
@chedabob yes keyboardWillShow is getting called. - Onichan
@LinusG. sure, but i already have println statements in each of the functions. where else should I add them? - Onichan
True but they are pretty useless for us if you don't show the output ;) - LinusGeffarth

1 Answers

2
votes

Set the gesture recognizer delegate to yourself and add the UIGestureRecognizerDelegate protocol.

func keyboardWillShow(notification: NSNotification) {
    if keyboardDismissTapGesture == nil
    {
        println("dismiss")
        keyboardDismissTapGesture = UITapGestureRecognizer(target: view, action: "dismissKeyboard:")
        keyboardDismissTapGesture.delegate = self
        self.view.addGestureRecognizer(keyboardDismissTapGesture!)
    }
}

Then add:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { 
    return true 
}

My guess is, the gesture of your table view is interfering with the new UITapGesture. Try this solution or else you should fail the gesture of your table view when your new UITapGesture is detected.

To fail the UITapGestureRecognizer of the table view I use this code:

if let recognizers = yourTableView.gestureRecognizers, let index = find(recognizers.map { $0 is UITapGestureRecognizer }, true) {
    (recognizers[index] as! UIPanGestureRecognizer).requireGestureRecognizerToFail(keyboardDismissTapGesture)
}

Maybe not the most elegant way of doing it, but it works for me when I want to fail the UIPanGestureRecognizer. I haven't tested it with the UITapGestureRecognizer.

EDIT:

if let recognizers = yourTableView.gestureRecognizers, let index = find(recognizers.map { $0 is UIGestureRecognizer }, true) {
    (recognizers[index] as! UIGestureRecognizer).requireGestureRecognizerToFail(keyboardDismissTapGesture!)
}