iOS closes virtual keyboard method aggregation
- 2020-05-27 07:13:54
- OfStack
In the development of the iOS application, there are three types of view objects that open the virtual keyboard for input, but there is no automatic method for how to close the virtual keyboard. We have to do it ourselves. The three types of view objects are UITextField,UITextView, and UISearchBar. Here are a few ways to turn off the virtual keyboard in UITextField.
The first method USES the method textFieldShouldReturn: in its delegate UITextFieldDelegate to close the virtual keyboard.
Implement this method in the class where the UITextField view object, such as birdNameInput, resides.
(BOOL)textFieldShouldReturn:(UITextField *)textField {
if ((textField == self.birdNameInput) || (textField == self.locationInput)) {
[textField resignFirstResponder];
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if ((textField == self.birdNameInput) || (textField == self.locationInput)) {
[textField resignFirstResponder];
}
return YES;
}
When the virtual keyboard is opened in the birdNameInput input box, tapping the return key automatically closes the virtual keyboard.
The second method modifies Return Key from the birdNameInput property to done, and then defines a method to connect Did End On Exit with the Done key.
This event is triggered by tapping the done key to close the virtual keyboard.
The method is defined as follows:
(IBAction) textFieldDoneEditing:(id)sender
{
[sender resignFirstResponder];
}
- (IBAction) textFieldDoneEditing:(id)sender
{
[sender resignFirstResponder];
}
Both methods tap a key on the virtual keyboard to close it. It's a precise operation, and unlike a mouse, it's not easy to do. So neither of these approaches is the best approach at the UI level. On an iphone or ipad screen, the virtual keyboard takes up a limited amount of space. Close the virtual keyboard by tapping the area outside the virtual keyboard.
The third method closes the virtual keyboard by tapping a blank area outside the keyboard.
Define an UITapGestureRecognizer object in the viewDidLoad method of the view controller class to which birdNameInput belongs, and assign it to its view.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[tap release];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[tap release];
Again, define the method dismissKeyboard that the selector calls under 1.
(void)dismissKeyboard {
[birdNameInput resignFirstResponder];
}
-(void)dismissKeyboard {
[birdNameInput resignFirstResponder];
}
If you have multiple textField on the screen, listing them one by one is a bit of a hassle. Then modify the method 1, as follows:
(void)dismissKeyboard {
NSArray *subviews = [self.view subviews];
for (id objInput in subviews) {
if ([objInput isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objInput;
if ([objInput isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
-(void)dismissKeyboard {
NSArray *subviews = [self.view subviews];
for (id objInput in subviews) {
if ([objInput isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objInput;
if ([objInput isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
If the view object on the screen is very complex, that's another story. This method is coded to create a new gesture object. You can also directly use the interface builder graphical development tool to pull a gesture object into the view controller class in storyboard, and then build an IBACTION gesture object with the name dismissKeyboard.
The fourth method closes the virtual keyboard by tapping a blank area outside the keyboard.
Drag an touch down event from the view or textField superview on the screen, and connect it to a method that closes the virtual keyboard. If the view does not have an touch down event, the parent class of view can be changed from UIView to UIButton. First, define and implement a method backgroundTap:.
(IBAction) backgroundTap:(id)sender
{
NSArray *subviews = [self.view subviews];
for (id objInput in subviews) {
if ([objInput isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objInput;
if ([objInput isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
- (IBAction) backgroundTap:(id)sender
{
NSArray *subviews = [self.view subviews];
for (id objInput in subviews) {
if ([objInput isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objInput;
if ([objInput isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
Then select the Touch Down event in the background view and connect backgroundTap:. This allows you to close the virtual keyboard with a single tap on the area outside the virtual keyboard. These methods all use the resignFirstResponder method to close the virtual keyboard, among others.
The fifth method, using endEditing: method, overrides the method in its view controller class.
(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign.
However, if the screen is complex, there are many buttons in the area outside the virtual keyboard. Tapping on these areas may result in tapping on the buttons so that the virtual keyboard cannot be closed.
If it is not easy to find a blank area without a button and there are hidden view objects, it is difficult to turn off the virtual keyboard by tapping the area outside the virtual keyboard.
The sixth method overrides the hitTest:withEvent: method to close the virtual keyboard
On stackoverflow.com, someone summed it up like this. Says using hitTest:withEvent: is the best and easiest solution.
I think the easiest (and best) way to do this is to subclass your global view and use hitTest:withEvent method to listen to any touch. Touches on keyboard aren't registered, so hitTest:withEvent is only called when you touch/scroll/swipe/pinch... somewhere else, then call [self endEditing:YES]. This is better than using touchesBegan because touchesBegan are not called if you click on a button on top of the view. It is better than UITapGestureRecognizer which can't recognize a scrolling gesture for example. It is also better than using a dim screen because in a complexe and dynamic user interface, you can't put dim screen every where. Moreover, it doesn't block other actions, you don't need to tap twice to select a button outside (like in the case of a UIPopover). Also, it's better than calling [textField resignFirstResponder], because you may have many text fields on screen, so this works for all of them.
So, I create another view class that inherits from UIView. In this view class, override the hitTest:withEvent: method and add the [self endEditing:YES] method.
(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *result = [super hitTest:point withEvent:event];
[self endEditing:YES]
return result;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *result = [super hitTest:point withEvent:event];
[self endEditing:YES]
return result;
}
I changed the class of the view controller's main view to this new view class. Tapping anywhere on the screen will close the virtual keyboard. This is the easiest and best way to turn off the virtual keyboard. Using the hitTest:withEvent: method, you can also achieve many very complex functions.
The implementation of hitTest:withEvent: in UIResponder does the following:
• It calls pointInside:withEvent: of self
• If the return is NO, hitTest:withEvent: returns nil. the end of the story.
• If the return is YES, it sends hitTest:withEvent: messages to its subviews. it starts from the top-level subview, and continues to other views until a subview returns a non-nil object, or all subviews receive the message.
• If a subview returns a non-nil object in the first time, the first hitTest:withEvent: returns that object. the end of the story.
• If no subview returns a non-nil object, the first hitTest:withEvent: returns self
This process repeats recursively, so normally the leaf view of the view hierarchy is returned eventually. However, you might override hitTest:withEvent to do something differently. In many cases, overriding pointInside:withEvent: is simpler and still provides enough options to tweak event handling in your application.
Above, we have introduced 6 ways to close the virtual keyboard of iOS, and you can choose a better way for yourself according to your personal needs. At the same time, thank you very much for your support of this site!