Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dismiss iOS Decimal keyboard?

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 -

  • Display the DONE key on the iOS keyboard?
  • Dismiss the keyboard?
like image 476
Harshit Gupta Avatar asked Aug 16 '14 20:08

Harshit Gupta


People also ask

How do I dismiss the keyboard in iOS?

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.

How do you dismiss keyboard when tapping outside TextField?

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.

How do I hide the TextField keyboard?

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.


4 Answers

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;
...
like image 103
Léo Natan Avatar answered Oct 22 '22 18:10

Léo Natan


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];
}
like image 2
Monikanta Avatar answered Oct 22 '22 19:10

Monikanta


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];
}
like image 1
wottle Avatar answered Oct 22 '22 19:10

wottle


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()
}
like image 1
A Fader Darkly Avatar answered Oct 22 '22 17:10

A Fader Darkly