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:
You can do it like below;
first, you should instance the view you want to add above the keyboard.
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
How to Get Managedobjectcontext for Viewcontroller Other Than Getting It from Appdelegate
How to Disable Afnetworking Cache
Custom Url to Launch Facebook Messenger on iOS
Custom Cordova Plugin: Add Framework to "Embedded Binaries"
"Could Not Find Developer Disk Image"
Removing New Line Characters from Nsstring
How to Draw a Line in the Simplest Way in Swift
Xcode 6 Upload App with Error: Itunes Store Operation Failed Error Description Not Available
When Exactly Do Implicit Animations Take Place in iOS
Change Uiimageview Size to Match Image with Autolayout
How to Play Video Stream with Mpmovieplayercontroller in iOS
Why Can't I Call the Default Super.Init() on Uiviewcontroller in Swift
Mfmailcomposeviewcontroller in iOS 7 Statusbar Are Black
Destinationviewcontroller Segue and Uinavigationcontroller Swift
Xcode 6 Save for Enterprise Deployment Does Not Create Plist for IPA Anymore