I am making an iOS application which required user to enter numeric values for multiple text fields. Under UITextField attributes, I have used
Keyboard = Decimal Pad
Return Key = Done
The keyboard is taking up the space and hiding the "Submit Form" Button.
Under the UIViewController.h file, I have written the following code for each UITextField, with event as Did end on Exit:
-(IBAction)dismissKeyboard:(id)sender;
Under the UIViewController.m file, I have written the following code for each UITextField:
-(IBAction)dismissKeyboard:(id)sender {
[textField becomeFirstResponder];
[textField resignFirstResponder];
}
When I open iOS simulator for Xcode 5, I do not get any DONE field on the on-screen keyboard. However, if I press RETURN key from my MacBook keyboard, the on-screen keyboard goes away.
How can I -
The first two are standard to the iOS system: Stop editing the note, and the keyboard will disappear. This requires clicking somewhere away from the text. Swipe your finger downwards beginning just above the keyboard, so that you catch the keyboard as you move.
First, you need to get the instance of FocusManager . Then, you can get the node that has the primary focus from the primaryFocus property whose type is FocusNode . If the primaryFocus is not null, you can call the unfocus() method of the FocusNode instance. Those can be done in a single line of code as shown below.
When you click on the TextField it opens up the on-screen keyboard. To hide/dismiss the keyboard you have to press the back button in Android and the done button (inside the onscreen keyboard) in iOS.
Since scroll view has been suggested, I will recommend another approach.
For each numeric input field, set an input accessory view - a toolbar - with a "Done" button in it. It will look like the bar above the keyboard in Safari. Once the user taps this Done button, close the keyboard like you normally do.
This is the simplest solution.
UIToolbar* toolbar = [UIToolbar new];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard:)];
id space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL];
toolbar.items = @[space, doneButton];
self.numericTextField1.inputAccessoryView = toolbar;
self.numericTextField2.inputAccessoryView = toolbar;
...
In .h class, first declare a scroll view.
@property (strong, nonatomic) IBOutlet UIScrollView *scrRegistration;
In .m class,use these code
-(void)viewWillAppear:(BOOL)animated
{
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard:)];
[gesture setNumberOfTapsRequired:1];
[gesture setNumberOfTouchesRequired:1];
[self.scrRegistration addGestureRecognizer:gesture];
[self.scrRegistration setContentSize:CGSizeMake(320, 354)];
for (UIView *vw in [self.scrRegistration subviews]) {
if([vw isKindOfClass:[UITextField class]]){
UITextField *txtfld=(UITextField *)vw;
txtfld.attributedPlaceholder = [[NSAttributedString alloc] initWithString:txtfld.placeholder attributes:@{NSForegroundColorAttributeName: [UIColor colorWithRed:8.0f/255.0f green:94.0f/255.0f blue:165.0f/255.0f alpha:1.0]}];
}
}
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField==DecimalKeyboard) {
if([[UIScreen mainScreen] bounds].size.height>480) {
[self.scrRegistration setContentOffset:CGPointMake(0, 110) animated:YES];
} else {
[self.scrRegistration setContentOffset:CGPointMake(0, 300) animated:YES];
}
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.barStyle = UIBarStyleBlackTranslucent;
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelNumberPad)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneWithNumberPad)],
nil];
[numberToolbar sizeToFit];
textField.inputAccessoryView = numberToolbar;
}
}
-(void)hideKeyboard:(UITapGestureRecognizer *)tap
{
[DecimalKeyboard resignFirstResponder];
[self.scrRegistration setContentOffset:CGPointMake(0, 0) animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView commitAnimations];
}
-(void)cancelNumberPad
{
for (UIView *vw in [self.scrRegistration subviews]) {
if([vw isKindOfClass:[UITextField class]]) {
UITextField *txtfld=(UITextField *)vw;
if ([txtfld isFirstResponder] == YES) {
[txtfld resignFirstResponder];
}
}
}
[self.scrRegistration setContentOffset:CGPointMake(0, 0) animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView commitAnimations];
}
-(void)doneWithNumberPad
{
[DecimalKeyboard resignFirstResponder];
[self.scrRegistration setContentOffset:CGPointMake(0, 0) animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView commitAnimations];
}
You might be better off simply putting the contents on screen into a scrollview, then resizing the view when the keyboard is present. That's typically the approach I take when I have an input form and it's very easy to implement. To do this, you can follow the instructions in this answer:
https://stackoverflow.com/a/16044603/3708242
First, make sure you register your viewController for the keyboard notifications (and remove the observers when the view is going away):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
Here's the main part of the code. It assumes you have a view that takes up the whole screen. If that's not the case, you'll need to tweak the CGRects in the two methods below.:
- (void)keyboardWillShow:(NSNotification *)note {
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
} completion:nil];
}
- (void)keyboardWillHide:(NSNotification *)note {
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
} completion:nil];
}
In case anyone else comes across this question when learning Swift, after a lot of failed attempts I finally had some success with this code in my ViewController, based on Leo Natan's answer above:
@IBOutlet var decimalField : UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// ...
addDoneButtonToKeyboard()
// ...
// Do any additional setup after loading the view, typically from a nib.
refreshUI()
}
func addDoneButtonToKeyboard() {
var doneButton:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "hideKeyboard")
var space:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
var items = [AnyObject]()
items.append(space)
items.append(doneButton)
toolbar.items = items
decimalField.inputAccessoryView = toolbar
}
func hideKeyboard() {
decimalField.resignFirstResponder()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With