I have tried some solutions that are out there, but they do not work they way I need them to.
I have quite a long text field that will have several paragraphs inside of it. When a user taps on the text field, their keyboard pops up and basically blocks about half the text that's already there and the keyboard prevents them from making any additions to the text field, since the user cannot see what they are typing.
I have tried modifying the frame definition to go above the keyboard, but since the textfield is so long, the user can still go below the keyboard if they add enough text. Wrapping the text view inside a scroll view doesn't do much either.
I am using swift + xcode 6
Here is a screenshot of what I am talking about:
Assuming you're using the autolayout, you can do the following :
In the .h, define a NSLayouConstraint :
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *keyboardHeight;
In the .m :
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [kbFrame CGRectValue];
self.keyboardHeight.constant = keyboardFrame.size.height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
self.keyboardHeight.constant = 20;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
}
Then link keyboardHeight with the vertical autolayout constraint between the UITextView and the bottom of the view :
Listen for the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification to adjust the size of your text view as is appropriate. You can get the dimensions of the keyboard via the UIKeyboardFrameEndUserInfoKey of the user dictionary.
E.g. a Swift version of Apple's code:
func keyboardWasShown(aNotifcation: NSNotification) {
let info = aNotifcation.userInfo as NSDictionary?
let rectValue = info![UIKeyboardFrameBeginUserInfoKey] as NSValue
let kbSize = rectValue.CGRectValue().size
let contentInsets = UIEdgeInsetsMake(0, 0, kbSize.height, 0)
textView.contentInset = contentInsets
textView.scrollIndicatorInsets = contentInsets
// optionally scroll
let aRect = textView.superview!.frame
aRect.size.height -= kbSize.height
let targetRect = CGRectMake(0, 0, 10, 10) // get a relevant rect in the text view
if !aRect.contains(targetRect.origin) {
textView.scrollRectToVisible(targetRect, animated: true)
}
}
Related
I have working code that pins UI to keyboard height when it appears:
- (void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
self.bottomSpacing.constant = kbSize.height + 10;
[self.view layoutIfNeeded];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
self.bottomSpacing.constant = 10;
[self.view layoutIfNeeded];
}
But it has issue when device autorotates: keyboard height changes (ex. on iPad 313 => 398) and 'bottomSpacing' becomes outdated.
How to update it to new keyboard height? Alternatively, is it possible to assign autolayout constraint to keyboard view?
The simplest way is to listen to UIKeyboardWillChangeFrameNotification notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillResize:) name:UIKeyboardWillChangeFrameNotification object:nil];
...
- (void)keyboardWillResize:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
float keyboardTop = CGRectGetMinY([info[UIKeyboardFrameEndUserInfoKey] CGRectValue]);
float animationDuration = info[UIKeyboardAnimationDurationUserInfoKey] floatValue];
[self.view layoutIfNeeded];
[UIView animateWithDuration:animationDuration animations:^{
self.pinToKeyboardConstraint.constant = keyboardTop;
[self.view layoutIfNeeded];
}];
}
This notification fires whenever the keyboard changes bounds including show and hide events.
My UIWebView is shifted up when the keyboard appears, and when the keyboard dismisses, the webview does not come back to its previous position. I've checked out the webview's position before and after the keyboard appears, or dismisses. What a surprise, the webview's frame is not changed. But what I've seen before and after are quite different.
Before the keyboard appears:
When the keyboard appears, the webview is shifted up
When the keyboard dismisses, the webview is not shifted down
What I did so far is applying the following techniques I read from others:
1) observe the keyboard notification, and adjust properly after that
observe keyboard notification
2) Change the meta tag, also add "height=device-height" in the meta tag
meta tag
3) Change the webview's attributes:
_webView.contentMode = UIViewContentModeScaleAspectFit;
_webView.scalesPageToFit = YES;
_webView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
However, all of these suggestion above do not work. Could you please help me?
Note: I use iOS7, XCODE 5
A UIWebView has a UIScrollView in it to manage content which is bigger than the screen. When you adjust the height of a UIScrollView it usually has an impact on it's scroll position. When you shrink the height with a keyboard it causes content to scroll up to keep the text field visible (by modifying the contentOffset), but when you expand the height it just shows more content at the bottom and doesn't change the contentOffset back to the original value.
There are slews of ways to come at this problem and everyone who creates an editable text deals with it at some point. I've used many over the years I'm sure there are probably better ones I haven't even seen.
The way I did it last was by modifying the contentInset of the UIScrollView and saving off the original contentOffset so I can re-populate it later.
Set up your notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
Do stuff on notifications
- (void)keyboardWillShow:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardRect = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat keyboardHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation)?keyboardRect.size.height:keyboardRect.size.width;
CGFloat duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
CGFloat animationStyle = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] floatValue];
self.tableViewOffset = self.tableView.contentOffset
UIEdgeInsets contentInsets = self.tableView.contentInset;
contentInsets.bottom = keyboardHeight;
[UIView animateWithDuration:duration delay:0 options:animationStyle animations:^{
self.tableView.contentInset = contentInsets;
} completion:nil];
}
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
CGFloat duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
CGFloat animationStyle = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] floatValue];
UIEdgeInsets contentInsets = self.tableView.contentInset;
contentInsets.bottom = 0;
[UIView animateWithDuration:duration delay:0 options:animationStyle animations:^{
self.tableView.contentInset = contentInsets;
self.tableView.contentOffset = self.tableViewOffset;
} completion:nil];
}
What I solved my problem is
1) observe when the keyboard dismisses:
- (void)observeKeyboard {
[NotificationCenter addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)removeObserveKeyboard
{
[NotificationCenter removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
2) When the keyboard is about to hide, we trigger a js to scroll it up.
- (void)keyboardWillHide:(NSNotification *)notification {
[self scrollBackToTop];
}
//- Fix bug: the UIWebView Content is scroll up when the keyboard appears
-(void)scrollBackToTop {
[_webView stringByEvaluatingJavaScriptFromString:#"window.scrollTo(0, 0);"];
}
Thanks to this link : link
Is there some way to get UIKeyboard size programmatically. 216.0f height and 162.0f height in landscape.
Following seem to be deprecated. Is there some way that works without any warning in both 3.0 iPhone OS SDK and 4.0 iPhone OS SDK to do this..
CGSize keyBoardSize = [[[note userInfo]
objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size;
You can get the keyboard size from the userInfo dictionary using the UIKeyboardFrameBeginUserInfoKey and the UIKeyboardFrameEndUserInfoKey instead.
These two keys return a NSValue instance containing a CGRect that holds the position and size of the keyboard at both the start and end points of the keyboard's show/hide animation.
Edit:
To clarify, the userInfo dictionary comes from an NSNotification instance. It's passed to your method that you register with an observer. For example,
- (void)someMethodWhereYouSetUpYourObserver
{
// This could be in an init method.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myNotificationMethod:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)myNotificationMethod:(NSNotification*)notification
{
NSDictionary* keyboardInfo = [notification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
}
Edit 2:
Also, please don't forget to remove yourself as an observer in your dealloc method! This is to avoid a crash that would occur when the notification center tries to notify your object after its been freed.
You should use the UIKeyboardWillChangeFrameNotification instead, because some international keyboards, like the Chinese keyboard, will change frames during use. Also make sure to convert the CGRect into the proper view, for landscape use.
//some method like viewDidLoad, where you set up your observer.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void)keyboardWillChange:(NSNotification *)notification {
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; //this is it!
}
Here's how I finally made works. I combined suggestions and codes from different answers.
Features: dismissing keyboard, moving text fields above keyboard while editing and setting "Next" and "Done" keyboard return type.REPLACE "..." with more fields
static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;
#interface ViewController () <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
.....// some other text fields
#property (weak, nonatomic) IBOutlet UITextField *emailTXT;
#end
#implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(tapScreen:)];// outside textfields
[self.view addGestureRecognizer:tapGesture];
// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];
// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];
// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}
// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
...
if([self.emailTXT isFirstResponder])[self.emailTXT resignFirstResponder];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
if(textField.returnKeyType==UIReturnKeyNext) {
// find the text field with next tag
UIView *next = [[textField superview] viewWithTag:textField.tag+1];
[next becomeFirstResponder];
} else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
[textField resignFirstResponder];
}
return YES;
}
// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
CGRect viewFrame = self.view.frame;
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//
CGFloat keyboardHeight = keyboardSize.height;
BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
if (isTextFieldHidden) {
animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
return YES;
}
-(void) restoreViewFrameOrigionYToZero{
CGRect viewFrame = self.view.frame;
if (viewFrame.origin.y != 0) {
viewFrame.origin.y = 0;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
-(void)keyboardDidShow:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
}
-(void)keyboardDidHide:(NSNotification*)aNotification{
[self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its zero origin
}
#end
On swift 4
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(getInfo(notif:)), name: .UIKeyboardDidShow , object: nil)
}
and then:
#objc func getInfo(notif: NSNotification) -> Void {
guard let userInfo = notif.userInfo else {return}
if let myData = userInfo["UIKeyboardFrameBeginUserInfoKey"] as? CGRect {
print(myData.width)
print(myData.height)
}
}
I have an embedded tableview within a view. The top rows of this embedded table view are always visible, even with the keyboard. If you enter something into the lower cells I want them to scroll up (as usual) in order to see what you're entering into the textfields. However this doesn't happen and they remain hidden behind the keyboard. How can I change this?
Thx
Michael
Here is a link with a detailed explanation to achieve this. It explains the method on UIScrollView, which will also work on UITableView.
If you had used a UITableViewController instead of manually adding UITableView on a view, you would had got the behavior automatically.
You have to scroll to the position between the TextField and Tableview, check this answer.
You don't get that behavior for free, you need to scroll the content up/down yourself. A UITableView inherits from a UIScrollView, so scrolling is not the actual problem. To scroll, you can set its contentSize and contentOffset (even animated if you like).
The first thing is, you want to listen to these notifications:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
These will tell you whether the keyboard will show or hide. In each of these methods, change the contentOffset and contentSize of your UITableView accordingly:
- (void)keyboardWillShow:(NSNotification *)notification
{
// keyboard info
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIViewAnimationOptions animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
NSTimeInterval animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// offsets
UIView *cell = myTextField.superView; // assuming your text field is a direct child of the UITableViewCell
CGFloat textFieldBottomY = self.view.frame.origin.y + myTableView.frame.origin.y - myTableView.contentOffset.y + cell.frame.origin.y + myTextField.origin.y + myTextField.frame.size.height;
CGFloat keyboardTopY = keyboardRect.origin.y;
// new content size: add size to be able to scroll
originalContentOffset = myTableView.contentOffset; // store the original content offset to set back when keyboard hides
originalContentSize = myTableView.contentSize; // store the original content size to set back when keyboard hides
CGSize newContentSize = myTableView.contentSize;
newContentSize.height += keyboardRect.size.height;
myTableView.contentSize = newContentSize;
// scroll to just beneath your text field
[UIView animateWithDuration:animationDuration delay:0 options:animationCurve animations:^{
myTableView.contentOffset = CGPointMake(0, textFieldBottomY - keyboardTopY);
} completion:NULL];
}
To reset everything:
- (void)keyboardWillHide:(NSNotification *)notification
{
// keyboard info
NSDictionary *userInfo = [notification userInfo];
UIViewAnimationOptions animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
NSTimeInterval animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// move content
[UIView animateWithDuration:animationDuration delay:0 options:animationCurve animations:^{
myTableView.contentOffset = originalContentOffset;
} completion:^(BOOL finished) {
if (finished) {
// reset content size
myTableView.contentSize = originalContentSize;
}
}];
}
To detect which text field is selected/active:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
myTextField = textField;
}
I didn't test out the code on a UITableView, but I used it very recently on a UIScrollView. Again - since a UITableView inherits from a UIScrollVIew, this should not be a problem. If the table view does not scroll correctly to just beneath the text field, the value of textFieldBottomY is incorrect.
Is there some way to get UIKeyboard size programmatically. 216.0f height and 162.0f height in landscape.
Following seem to be deprecated. Is there some way that works without any warning in both 3.0 iPhone OS SDK and 4.0 iPhone OS SDK to do this..
CGSize keyBoardSize = [[[note userInfo]
objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size;
You can get the keyboard size from the userInfo dictionary using the UIKeyboardFrameBeginUserInfoKey and the UIKeyboardFrameEndUserInfoKey instead.
These two keys return a NSValue instance containing a CGRect that holds the position and size of the keyboard at both the start and end points of the keyboard's show/hide animation.
Edit:
To clarify, the userInfo dictionary comes from an NSNotification instance. It's passed to your method that you register with an observer. For example,
- (void)someMethodWhereYouSetUpYourObserver
{
// This could be in an init method.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myNotificationMethod:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)myNotificationMethod:(NSNotification*)notification
{
NSDictionary* keyboardInfo = [notification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
}
Edit 2:
Also, please don't forget to remove yourself as an observer in your dealloc method! This is to avoid a crash that would occur when the notification center tries to notify your object after its been freed.
You should use the UIKeyboardWillChangeFrameNotification instead, because some international keyboards, like the Chinese keyboard, will change frames during use. Also make sure to convert the CGRect into the proper view, for landscape use.
//some method like viewDidLoad, where you set up your observer.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void)keyboardWillChange:(NSNotification *)notification {
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; //this is it!
}
Here's how I finally made works. I combined suggestions and codes from different answers.
Features: dismissing keyboard, moving text fields above keyboard while editing and setting "Next" and "Done" keyboard return type.REPLACE "..." with more fields
static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;
#interface ViewController () <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
.....// some other text fields
#property (weak, nonatomic) IBOutlet UITextField *emailTXT;
#end
#implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(tapScreen:)];// outside textfields
[self.view addGestureRecognizer:tapGesture];
// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];
// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];
// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}
// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
...
if([self.emailTXT isFirstResponder])[self.emailTXT resignFirstResponder];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
if(textField.returnKeyType==UIReturnKeyNext) {
// find the text field with next tag
UIView *next = [[textField superview] viewWithTag:textField.tag+1];
[next becomeFirstResponder];
} else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
[textField resignFirstResponder];
}
return YES;
}
// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
CGRect viewFrame = self.view.frame;
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//
CGFloat keyboardHeight = keyboardSize.height;
BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
if (isTextFieldHidden) {
animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
return YES;
}
-(void) restoreViewFrameOrigionYToZero{
CGRect viewFrame = self.view.frame;
if (viewFrame.origin.y != 0) {
viewFrame.origin.y = 0;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
-(void)keyboardDidShow:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
}
-(void)keyboardDidHide:(NSNotification*)aNotification{
[self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its zero origin
}
#end
On swift 4
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(getInfo(notif:)), name: .UIKeyboardDidShow , object: nil)
}
and then:
#objc func getInfo(notif: NSNotification) -> Void {
guard let userInfo = notif.userInfo else {return}
if let myData = userInfo["UIKeyboardFrameBeginUserInfoKey"] as? CGRect {
print(myData.width)
print(myData.height)
}
}