简体   繁体   中英

iOS Hide keyboard when tapping outside of an uitextfield, located in a subview?

I am new at this (also i am from argentina, sorry for my basic english), and i REALLY don't know what to do with this problem. I have a view, that contains a UIScrollView to scroll the View, and inside i have a subView that contains a lot of UITextField . The point is to hide keyboard when I touch outside of the UITextField , but I think the touch event is not triggered (I don't know why, maybe you can help me). I am also a newbie in iOS, but I am learning! Thanks!

EDIT: First, thanks to all for answering! For all who said to disable usar interaction, it works for UITextFields, but now i can't interact with UITable's inside de subview! Any help?

try this

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [self.view endEditing:YES];    
    }

or this

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UIView * youtxtfl in self.view.subviews){
        if ([youtxtfl isKindOfClass:[UITextField class]] && [youtxtfl isFirstResponder]) {
            [youtxtfl resignFirstResponder];
        }
    }
}

The Scroll View is going to intercept the gesture recogniser, you will need to disable the user interaction on the view AFTER you click on the text field.

You can do this via;

scrollView.userInteractionEnabled = NO;

Hope this will help you :)

- (void)viewDidLoad
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(dismissKeyboard)];
        [self.view addGestureRecognizer:tap];
}



    -(void)dismissKeyboard
    {
    [svScrollView setContentOffset:CGPointMake(0, 0) animated:YES];

        [self resignFirstResponder];

    }

There is property in XIB file, please find below screenshot.

XIB Scrollview属性

Swift:

The next solution is for UITextView, but you can modify it for UITextField

1) Add keyboardWillShow event handler in the view controller that contains the field and save a reference to the field

/**
Listen keyboard events

:param: animated the animation flag
*/
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    initNavigation()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}

/**
Remove self as keyboard listener

:param: animated the animation flag
*/
override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}

/**
Save reference to focused textView

:param: sender the sender
*/
func keyboardWillShow(sender: AnyObject){
    if self.searchTextField?.isFirstResponder() ?? false {
        KeyboardDismissingUIViewTarget = self.searchTextField
    }
}

/**
Clean KeyboardDismissingUIViewTarget

:param: sender the sender
*/
func keyboardWillHide(sender: AnyObject){
    KeyboardDismissingUIViewTarget = nil
}

2) Use custom class for top most UIView:

/// the target view (textView) which should not dismiss the keyboard
var KeyboardDismissingUIViewTarget: UIView?

/**
* Custom class for top view that dismisses keyboard when tapped outside the given textView or textField
*
* @author Alexander Volkov
* @version 1.0
*/
class KeyboardDismissingUIView: UIView {

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        if let targetView = KeyboardDismissingUIViewTarget as? UITextView {

            // Convert the point to the target view's coordinate system.
            // The target view isn't necessarily the immediate subview
            let pointForTargetView = targetView.convertPoint(point, fromView: self)

            if CGRectContainsPoint(targetView.bounds, pointForTargetView) {
                return targetView.hitTest(pointForTargetView, withEvent: event)
            }
            else {
                KeyboardDismissingUIViewTarget = nil
                targetView.resignFirstResponder()
                return nil
            }
        }
        return super.hitTest(point, withEvent: event)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM