How to Mimic Keyboard Animation on iOS 7 to Add "Done" Button to Numeric Keyboard

How to mimic Keyboard animation on iOS 7 to add Done button to numeric keyboard?

In iOS 7, the keyboard uses a new, undocumented animation curve. While some have noted that using an undocumented value for the animation option works, I prefer to use the following:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];

// work

[UIView commitAnimations];

While block based animations are the recommendation, the animation curve returned from the keyboard notification is an UIViewAnimationCurve, while the option you would need to pass to block based animations is an UIViewAnimationOptions. Using the traditional UIView animation methods allows you to pipe the value directly in. Most importantly, this will use the new undocumented animation curve (integer value of 7) and cause the animation to match the keyboard. And, it will work just as well on iOS 6 and 7.

iOS 7 - Keyboard animation

Now I found the solution. The animation starts from the point {0, 920} to {0, 352}. The problem was that the UITableView object started with a size of {160, 568}, so I changed the size of the UITableView to {160, 920} before the animation was started.

Concerning to the unknown animation curve, I just set the parameter to animationCurve << 16 to convert it from a view animation curve to a view animation option.

The value is not equal to the linear, ease in, ease out and ease inout animation curve.

Here is my code:

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];

and:

- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;

//
// Get keyboard size.

NSValue *beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardBeginFrame = [self.view convertRect:beginFrameValue.CGRectValue fromView:nil];

NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];

//
// Get keyboard animation.

NSNumber *durationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration = durationValue.doubleValue;

NSNumber *curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey];
UIViewAnimationCurve animationCurve = curveValue.intValue;

//
// Create animation.

CGRect tableViewFrame = self.tableView.frame;
bTableViewFrame.size.height = (keyboardBeginFrame.origin.y - tableViewFrame.origin.y);
self.tableView.frame = tableViewFrame;

void (^animations)() = ^() {
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = (keyboardEndFrame.origin.y - tableViewFrame.origin.y);
self.tableView.frame = tableViewFrame;
};

//
// Begin animation.

[UIView animateWithDuration:animationDuration
delay:0.0
options:(animationCurve << 16)
animations:animations
completion:nil];
}

UIKeyboardWillChangeFrameNotification UIViewAnimationCurve set to 7 on iOS 7

It seems that the keyboard is using an undocumented/unknown animation curve.

But you can still use it. To convert it to a UIViewAnimationOptions for block animations shift it by 16 bits like so

UIViewAnimationCurve keyboardTransitionAnimationCurve;
[[notification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey]
getValue:&keyboardTransitionAnimationCurve];

keyboardTransitionAnimationCurve |= keyboardTransitionAnimationCurve<<16;

[UIView animateWithDuration:0.5
delay:0.0
options:keyboardTransitionAnimationCurve
animations:^{
// ... do stuff here
} completion:NULL];

Or just pass it in as an animation curve.

UIViewAnimationCurve keyboardTransitionAnimationCurve;
[[notification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey]
getValue:&keyboardTransitionAnimationCurve];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:keyboardTransitionAnimationCurve];
// ... do stuff here
[UIView commitAnimations];

How to add Done button to Numpad in iOS using Swift?

As far as I know, you can't add the Done button on the keyboard part; you'd have add a inputAccessoryView to the UITextField or UITextView (if that's what you're using).

Check the documentation for more info.

Edit: Check this question for an example on how to do that.

Edit 2: Similar example in Swift.

Edit 3: Code from edit 2, as link may expire.

override func viewDidLoad()
{
super.viewDidLoad()

//--- add UIToolBar on keyboard and Done button on UIToolBar ---//
self.addDoneButtonOnKeyboard()
}

//--- *** ---//

func addDoneButtonOnKeyboard()
{
var doneToolbar: UIToolbar = UIToolbar(frame: CGRectMake(0, 0, 320, 50))
doneToolbar.barStyle = UIBarStyle.BlackTranslucent

var flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: Selector("doneButtonAction"))

var items = NSMutableArray()
items.addObject(flexSpace)
items.addObject(done)

doneToolbar.items = items
doneToolbar.sizeToFit()

self.textView.inputAccessoryView = doneToolbar
self.textField.inputAccessoryView = doneToolbar

}

func doneButtonAction()
{
self.textViewDescription.resignFirstResponder()
}

Swift 4.2

func addDoneButtonOnKeyboard(){
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default

let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))

let items = [flexSpace, done]
doneToolbar.items = items
doneToolbar.sizeToFit()

txtMobileNumber.inputAccessoryView = doneToolbar
}

@objc func doneButtonAction(){
txtMobileNumber.resignFirstResponder()
}

Receiving notifications from custom 'Done' button on numeric keyboard not working in iOS 8.3

I had the same problem, I solved this issue by adding button directly on UITextEffectsWindow. Also I've changed the button frame.

- (void)addButtonToKeyboar {
// create custom button
self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.doneButton.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 53, [[UIScreen mainScreen] bounds].size.width / 3, 53);
self.doneButton.adjustsImageWhenHighlighted = NO;
[self.doneButton setTag:67123];
[self.doneButton setImage:[UIImage imageNamed:@"doneup1.png"] forState:UIControlStateNormal];
[self.doneButton setImage:[UIImage imageNamed:@"donedown1.png"] forState:UIControlStateHighlighted];

[self.doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];

// locate keyboard view
int windowCount = [[[UIApplication sharedApplication] windows] count];
if (windowCount < 2) {
return;
}

UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIButton* donebtn = (UIButton*)[tempWindow viewWithTag:67123];
if (donebtn == nil)//to avoid adding again and again as per my requirement (previous and next button on keyboard)
[tempWindow addSubview:self.doneButton]; }

How to add buttons above keyboard

The first question, you can set textField's inputAccessoryView to your custom view, this can customize the keyboard's header.

The result:

Sample Image

You can do it like below;

first, you should instance the view you want to add above the keyboard.

Sample Image

class ViewController : UIViewController {

@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()

textField.inputAccessoryView = Bundle.main.loadNibNamed("CustomAccessoryView", owner: self, options: nil)?.first as! UIView?

In your CustomAccessoryView, you can set the action of the button:

import UIKit

class CustomAccessoryView: UIView {

@IBAction func clickLoveButton(_ sender: UIButton) {

print("Love button clicked")
}
}

Is it possible to add done button inside the keyboard in iphone?

Here is to be a good tutorial about this.



Related Topics



Leave a reply



Submit