Reputation: 3119
I am building a converter app. In the main screen I have a text field to input numbers and below the text field a picker view will allow users to select conversion parameters, (for example kg to g).
I can hide the keyboard when user click the background by using the following method
(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.enterInput resignFirstResponder];
but when I touch the picker view the keyboard is not hiding.
My question is how to dismiss the keyboard when a user touches the picker view.
Upvotes: 2
Views: 2859
Reputation: 6352
I use this in my code. I climb the responder chain and reassign the responder. I put this in my method that shows the pickerView. So far no unexpected issues. Seems to work if a keyboard was showing and seems not to crash if there wasn't a keyboard showing.
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
Upvotes: 1
Reputation: 3119
Got a solution
1) First Create a hidden roundRect botton and change the type to custom (fit the size of the picker).
2) Create a touch up inside action
- (IBAction)hiddenButtonToHideKeyboard:(id)sender {
[self.enterInput resignFirstResponder];
}
3) Create a keyboard appear notification
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onKeyboardAppear:) name:UIKeyboardWillShowNotification object:nil];
4) Create a keyboard disappear notification
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onKeyboardHide:) name:UIKeyboardWillHideNotification object:nil];
5) Make the button visible when keyboard is appeared
-(void)onKeyboardAppear:(NSNotification *)notification
{
hiddenButtonToHideKeyboard.hidden=NO;
}
6) Hide the button when the keyboard is disappeared
-(void)onKeyboardHide:(NSNotification *)notification
{
hiddenButtonToHideKeyboard.hidden=YES;
}
5) done
I dont think it is a perfect solution but it works for me :)
Upvotes: 2
Reputation: 1031
Here you go. UIPickerViews are a fairly complex system of nested UIViews which is why you weren't getting any response from the touchesBegan:withEvent:
method. What you can do is create your UIPickerView subclass as follows:
//
// MyPickerView.h
//
#import <UIKit/UIKit.h>
// Protocol Definition that extends UIPickerViewDelegate and adds a method to indicate a touch
@protocol MyPickerViewDelegate <UIPickerViewDelegate>
// This is the method we'll call when we've received a touch. Our view controller should implement it and hide the keyboard
- (void)pickerViewDidReceiveTouch:(UIPickerView *)pickerView;
@end
@interface MyPickerView : UIPickerView
// We're redefining delegate to require conformity to the MyPickerViewDelegate protocol we just made
@property (nonatomic, weak) id <MyPickerViewDelegate>delegate;
@end
//
// MyPickerView.m
//
#import "MyPickerView.h"
@implementation MyPickerView
@synthesize delegate = _myPickerViewDelegate; // We changed the data type of delegate as it was declared in the superclass so it's important to link it to a differently named backing variable
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// We make sure to call the super method so all standard functionality is preserved
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView) {
// This will be true if the hit was inside of the picker
[_myPickerViewDelegate pickerViewDidReceiveTouch:self];
}
// Return our results, again as part of preserving our superclass functionality
return hitView;
}
@end
Then in your ViewController change it to conform to <MyPickerViewDelegate>
instead of <UIPickerViewDelegate>
. This is ok since MyPickerViewDelegate
inherits from UIPickerViewDelegate
and will pass through the standard UIPickerViewDelegate
methods.
Finally implement pickerViewDidReceiveTouch:
in your view controller:
- (void)pickerViewDidReceiveTouch:(UIPickerView *)pickerView {
[enterInput resignFirstResponder];
}
Upvotes: 0