4

I've googled on how to dismiss keyboard when touching a blank area in UITableView in iOS, and there're several ways to solve this. Like using delegate, UITapGestureRecognizer, - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event and - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event.

I decide to take hitTest by subclassing the corresponding UIView class and override this method like this:

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *result = [super hitTest:point withEvent:event];
    [self endEditing:YES];

    return result;
}

This really works, will dismiss the virtual keyboard when I touch / scroll / swipe / pinch ... somewhere else, but another problem shows up.

The keyboard is active or shown when I touch one UITextField object, then I touch the same UITextField object, here is the problem, the keyboard try to dismiss but not completely, in the middle of somewhere it begin to show up, doing this kind of weird animation. Most of the case in our APPs, the keyboard should stay still when we touch the same UITextField object. Is there a nice and simple way to solve this problem?

Solved: Finally, I figure it out myself. Thanks to @Wain, thanks to @Wain's hint. I do check the result before I invoke [self endEditing:YES];. Here is the modified code:

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *result = [super hitTest:point withEvent:event];
    // You can change the following condition to meet your own needs
    if (![result isMemberOfClass:[UITextField class]] && ![result isMemberOfClass:[UITextView class]]) {
        [self endEditing:YES];
    }
    return result;
}
iBCode
  • 43
  • 5
  • Why don't you check what `result` is before ending the edit session? – Wain Jun 26 '14 at 07:25
  • use this link it is hope for u http://stackoverflow.com/questions/23652079/ios-dismissing-keyboard-uilabel-malfunction/23652253#23652253 – Anbu.Karthik Jun 26 '14 at 07:26
  • 1
    or otherwise change this [self endEditing:YES]; into [self.view endEditing:YES]; – Anbu.Karthik Jun 26 '14 at 07:27
  • 1
    @Wain How to check, like if the `result` is UITextField object, return directly and skip the endEditing, can you describe more detail? – iBCode Jun 26 '14 at 07:38
  • @Anbu.Karthik The link doesn't work for me, `-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event` doesn't work if the view subclasses from UIScrollView. Meanwhile, I override this method in a subclass of UITableView, thus, it could lead to error if I change `[self endEditing:YES];` into `[self.view endEditing:YES];`, cause `self` is the view itself. – iBCode Jun 26 '14 at 07:42
  • r u used in scrollview, if u use scrollview then change into [self.ScrollView endEditing:YES]; – Anbu.Karthik Jun 26 '14 at 07:48
  • @Anbu.Karthik Yes, it's scrollview. Because my custom view class is a subclass of UITableView, and UITableView is a subclass of UIScrollView. The point is I override this method in my custom view, not in any view controller. Thus, `[self.scrollView endEditing:YES]` will cause syntax error. Because `self` is pointing to the view, like I said, `self` is the view itself. – iBCode Jun 26 '14 at 08:04

2 Answers2

1

As per @iBCode answer, if I select same text field multiple times then keyboard automatically hide and show immediately, to avoid that I have added one more condition and added code below in swift languagge

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    if let resultView = super.hitTest(point, with: event) {
        if resultView.isMember(of: UITextField.self) ||
            resultView.isKind(of: UITextField.self) ||
            resultView.isMember(of: UITextView.self) ||
            resultView.isKind(of: UITextView.self) {
            return resultView
        }
        if !resultView.isMember(of: UITextField.self) && !resultView.isMember(of: UITextView.self) {
            endEditing(true)
        }
        return resultView
    }
    return nil
}
Anjaneyulu Battula
  • 1,910
  • 16
  • 33
0

Check the class of the result so that you can limit when you end editing. If the hit target was an editable class (like a text field, or a switch) then don't end the editing session.

Wain
  • 118,658
  • 15
  • 128
  • 151