The keyboard info dictionary is returning incorrect numbers for the emoji keyboard height. If I click on the textfield it animates up the normal keyboard fine but when i click on the emoji's it still thinks the height is the standard keyboard. Why? And is there a way to get the alternate (emoji) keyboard height programatically. The constant 37 is a terrible hack that I put in to get it to work.
- (void)keyboardWillShow:(NSNotification *)notification {
if (!IS_SHOWING_KEYBOARD) {
IS_SHOWING_KEYBOARD=YES;
NSDictionary *userInfo = [notification userInfo];
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
[self.view layoutIfNeeded];
self.commentTopLayout.constant -= keyboardSize.height;
self.commentBottomLayout.constant -= keyboardSize.height;
[UIView animateWithDuration:0.2f animations:^{
[self.view layoutIfNeeded];
}];
} else { //move him down, then up again. //clicked on emojis
NSDictionary *userInfo = [notification userInfo];
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
[self.view layoutIfNeeded];
self.commentTopLayout.constant += keyboardSize.height;
self.commentBottomLayout.constant += keyboardSize.height;
[UIView animateWithDuration:0.2f animations:^{
[self.view layoutIfNeeded];
}];
[self.view layoutIfNeeded];
self.commentTopLayout.constant -= keyboardSize.height+37;
self.commentBottomLayout.constant -= keyboardSize.height+37;
[UIView animateWithDuration:0.2f animations:^{
[self.view layoutIfNeeded];
}];
}
}
I had the same problem. Just replace UIKeyboardFrameBeginUserInfoKey with UIKeyboardFrameEndUserInfoKey . :-)
Related
I need to move a keyboard up and down. I have many subviews with many uiTextfields. These subviews has one superview and this superview is in the scroll view.
I can't move up a view using below code:
- (void) keyboardWasShown:(NSNotification *)notification{
NSDictionary *info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey]CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0);
self.Scroll_view.contentInset = contentInsets;
self.Scroll_view.scrollIndicatorInsets = contentInsets;
}
- (void) keyboardWillBeHidden:(NSNotification *)notification{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.Scroll_view.contentInset = contentInsets;
self.Scroll_view.scrollIndicatorInsets = contentInsets;
}
This code working fine when i place all the UITextfields in the ScrollView(Not into the subviews), But i need to do with subview and also move keyboard up and down.
How can i move a keyboard up and down while press keyboard Next/Return key?
Try This:
- (void)animateViewUpToTargetYOrigin:(CGFloat)yValue
{
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidChangeFrameNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
CGFloat yOrigin = 0;
CGFloat keyboardYOrigin = [[[note userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
if (yValue > keyboardYOrigin) {
yOrigin = yValue - keyboardYOrigin;
}
[UIView animateWithDuration:0.3f animations:^{
self.view.frame = CGRectMake(self.frame.origin.x, -yOrigin, self.frame.size.width, self.frame.size.height);
}];
}];
Using this code you only need to call this method in textfield didbeginediting, and pass the yOrigin(textfield)+height(textField) as y value in it.
If you textFields are in Scrollview or any sub view convert their frame values in respect to self.view before sending Y value.
E.g:
CGRect textFieldRectWithRespectToSelfView = [textField.superview convertRect:textField.frame toView:self.view];
[self.view animateViewUpToTargetYOrigin: textFieldRectWithRespectToSelfView.orgin.y + textFieldRectWithRespectToSelfView.size.height];
When you call [textField resignFirstResponder], self.view comes back to its original position. This happens because the UIKeyboardDidChangeFrameNotification always keeps listening to keyboard frame changes.
I do have a demo project in github as an example please refer to it:
https://github.com/subhajitregor/ViewMoveUpExample
In viewDidLoad method
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
// the keyboard is hiding reset the table's height
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.view.frame;
frame.origin.y += 150;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
// the keyboard is showing so resize the table's height
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.view.frame;
frame.origin.y -= 150;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
}
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.
I have a TableView inside a UIViewController created in Main.Storyboard.
The Y-position is 0 when initialized.
My problem is, when the keyboard shows, the Y-Position of the TableView doesn't change at all. The Y-position stays at 0. So the cells get's hidden behind the NavigationController.
The code so far:
-(void) keyboardWasShown:(NSNotification*)aNotification
{
if (kbIsShown == false) {
NSDictionary* info = [aNotification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
NSLog(#"frame..%f..%f..%f..%f",self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
NSLog(#"keyboard..%f..%f..%f..%f",keyboardFrame.origin.x, keyboardFrame.origin.y, keyboardFrame.size.width, keyboardFrame.size.height);
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[chatTable setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height + TABBAR_HEIGHT, self.view.frame.size.width, self.view.frame.size.height-keyboardFrame.size.height)];
[UIView commitAnimations];
NSLog(#"Visar sig");
kbIsShown = true;
}
}
The [chatTable setFrame:] doesn't do anything. The TableViews (chatTable) Y-position stays at 0. How can i change the Y-position of the Tableview so my content will be visible?
Note: [self.view setFrame...] does actually change the Y-position of the view. But the chatTable stays at 0.
In order to scroll your table view to desired row use:
[chatTable scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
you should also set:
chatTable.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0);
I have a UIView with a UITextField placed at the bottom of the screen which I'd like to move up when a keyboard appears.
I have added keyboardFrameDidChange observer for getting notified whenever a keyboard appears/disappears. Here is the method :
-(void)keyboardFrameDidChange:(NSNotification*)notification{
NSDictionary* info = [notification userInfo];
CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
[bottomView layoutIfNeeded];
[UIView animateWithDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue] delay:0 options:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue] animations:^{
[bottomView setFrame:CGRectMake(0, kKeyBoardFrame.origin.y - bottomView.frame.size.height, 320, bottomView.frame.size.height)];
} completion:^(BOOL finished) {
[bottomView layoutIfNeeded];
NSLog(#"frame ** %f",self.bottomView.frame.origin.y);
}];
}
Here the frame of bottomView is changing but nothing happens in the UI. The bottomView just remains at the bottom. What might be the reason?
This sounds like an auto layout problem. If auto layout is on, then you should change the view's position by adjusting its constraints, not setting frames. Make an IBOutlet to the constraint between the text field and the bottom of superview (bottomCon in my example), and adjust it.
-(void)keyboardFrameDidChange:(NSNotification*)notification{
NSDictionary* info = [notification userInfo];
CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
[_bottomView layoutIfNeeded];
[UIView animateWithDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue] delay:0 options:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue] animations:^{
self.bottomCon.constant = kKeyBoardFrame.origin.y;
[_bottomView layoutIfNeeded];
} completion:^(BOOL finished) {
NSLog(#"frame ** %f",self.bottomView.frame.origin.y);
}];
}
I'm going crazy. I'll try to move the ToolBar with its textfield when the key board is appearing. With the following code the view is really moving but the ToolBar stays and gets hidden by the keyboard:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
NSDictionary* userInfo = [aNotification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[UIView commitAnimations];
}
I'm a beginner so please don't beat me up but I don't know the missing link to move and show the ToolBar with its textfield.
The toolbar and the textfield is created in the viewDidLoad method.
I figured out that the ToolBar itself has to move with the keyboard:
This prevents it from get hidden by the appearing keyboard:
When using a ToolBar in a NavigationController the following code should do the trick:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification
{
NSDictionary* userInfo = [aNotification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.navigationController.toolbar setFrame:CGRectMake(self.navigationController.toolbar.frame.origin.x,
self.navigationController.toolbar.frame.origin.y - keyboardFrame.size.height +self.navigationController.toolbar.frame.size.height,
self.navigationController.toolbar.frame.size.width,
self.navigationController.toolbar.frame.size.height)];
[UIView commitAnimations];
}
All the other necessary code is pretty well described HERE.
self.view does not contain the toolbar, you have to move the toolbar separately ...