2
votes

I have a tap gesture recognizer that I use to dismiss keyboard and store some data from a textfield. On the same view I have a tableview with didSelectRowAtIndexPath. When I tap on a row my gesture recognizer gets called instead of uitableview method. I've searched stack overflow and found some obj c solutions that I tried to implement. The solution is to implement cancelsTouchesInView and set it to NO. Below is my tap gesture recognizer function that doesn't seem to work. Am I doing something wrong ?

func addTapGestureRecognizer(){
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(detailViewController.dismissKeyboard))
    self.view.addGestureRecognizer(tap)
    tap.cancelsTouchesInView = false;
}

This is my didSelectRowAtIndexPath

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    print("Stisnut Redak")

    let selectedRowObject = arrayForSteps[indexPath.row]

    if selectedRowObject.status == false {
        tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
    } else {
        tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
    }

}
2

2 Answers

2
votes

the way that I would implement this is to use the:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool

delegate method from the UIGestureRecognizerDelegate protocol (you need to make sure you declare that the controller which has scope over the table view, keyboard and text field signs up to this protocol). This will intercept the tap gesture and ask the function to determine whether the tap should be handled by the tap gesture recognizer or some other object.

So what you could do in your implementation of this method is check the following:

if self.myTableViewController.tableView.frame.contains(touch.location(in: self.view)) {
        return false // The touch will be handled by the table view instead
    }
    return true  // The touch will be handled by the tap gesture recognizer, etc.

The nice thing about this is that you don't have to add any further code to handle the return false case as the touch will then be handled by the next appropriate responder automatically.

(Another way you could do this if you did not want to use the above would be to create an action that tests whether the keyboard is currently being presented within the viewController's view, and decide on the basis of that what action to take.)

Hope that helps!

1
votes

You can do this. Take a BOOL as an instance variable isKeyboardActive and set it to YES in textFieldDidBeginEditing and set it to NO in textFieldDidEndEditing. Also set it to NO in viewDidLoad.

Now implement this method -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event and check if isKeyboardActive is YES. If so then implement [self.view endEditing:YES]. If this doesn't work or is not required then please explain your question further so that we can help it out.