I am using a UIView with a button at the bottom of the view.
I want to move the button right above the keyboard when the keyboard shows / changes height.
The code I am using is:
- (void)keyboardFrameDidChange:(NSNotification *)notification
{
CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect newFrame = self.view.frame;
CGRect keyboardFrameEnd = [self.view convertRect:keyboardEndFrame toView:nil];
CGRect keyboardFrameBegin = [self.view convertRect:keyboardBeginFrame toView:nil];
newFrame.origin.y -= (keyboardFrameBegin.origin.y - keyboardFrameEnd.origin.y);
self.view.frame = newFrame;
}
and in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardFrameDidChange:) name:UIKeyboardDidChangeFrameNotification object:nil];
this code works find on iPhone6, but if it is in iPhone 5 and using a Chinese keyboard there will be a black space:
Related
So I'm not sure why my code isn't working. When the keyboard appears it puts the toolBar above the keyboard, but much higher than the height of the keyboard. Also the quick text bar in ios8 messes it up even more when I toggle it on and off, and the toolBar doesn't adjust correctly. Also when I close out the keyboard the first time the toolBar goes back to its original position, but then after once it doesn't go back down all the way where it was originally. I logged out self.yPositionStore and it never changes, which is why I don't understand why it doesn't always go back to the same spot. I've literally been working on this code all day trying to find a solution to my textfield getting hidden by the keyboard and it's giving me a headache. someone PLEASE help me.
- (void)viewDidLoad {
[super viewDidLoad];
self.yPositionStore = self.toolBar.frame.origin.y;
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect newFrame = self.toolBar.frame;
newFrame.origin.y = kbSize.height;
self.toolBar.frame = newFrame;
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
CGRect newFrame = self.toolBar.frame;
newFrame.origin.y = self.yPositionStore;
self.toolBar.frame = newFrame;
}
There was problem in keyboardwasshown method. you have to subtract toolbar height and keyboard height from main screen height to find exact y value for toolbar.
- (void)viewDidLoad {
[super viewDidLoad];
self.yPositionStore = self.toolBar.frame.origin.y;
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect newFrame = self.toolBar.frame;
newFrame.origin.y = [UIScreen mainscreen].bounds.size.height - kbSize.height - newFrame.size.height;
self.toolBar.frame = newFrame;
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
CGRect newFrame = self.toolBar.frame;
newFrame.origin.y = self.yPositionStore;
self.toolBar.frame = newFrame;
}
ok so for the most part this winded up working
- (void)keyboardWasShown:(NSNotification*)aNotification
{
self.yPositionStore = self.toolBar.frame.origin.y;
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGRect newFrame = self.toolBar.frame;
newFrame.origin.y = [UIScreen mainScreen].bounds.size.height - kbSize.height - newFrame.size.height;
self.toolBar.frame = newFrame;
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
CGRect newFrame = self.toolBar.frame;
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
newFrame.origin.y += kbSize.height - newFrame.size.height;
self.toolBar.frame = newFrame;
}
After the first time the keyboard is hidden, the tool bar goes down about a pixel further than it's suppose to, but it still looks good. The other problem I'm still having is on keyboardWasShown, the toolbar is repositioning itself but it's a little bit delayed, and I'm not sure how to fix that. Now off to trying out how to reposition a tableview with the keyboard!
I am developing a chat application which has textview and other buttons placed on a view. I have an issue with iOS8 keyboard when predictive is set on.
When predictive is off it is working fine but it is set on my view in which textview and other buttons are placed is displaces.
I added NSNotification for KeyboardWillShow and KeyboardWillHide in viewDidLoad.
viewDummy is a view where textview and other buttons are added
- (void)keyboardWillShow:(NSNotification *)notification {
NSDictionary* info = [notification userInfo];
CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.2f animations:^{
CGRect frame = viewDummy.frame;
frame.origin.y -= kbSize.height;
viewDummy.frame = frame;
frame = bubbleTable.frame;
frame.size.height -= kbSize.height;
bubbleTable.frame = frame;
}];
}
-(void) keyboardWillHide:(NSNotification *)note{
NSDictionary* info = [note userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.2f animations:^{
CGRect frame = viewDummy.frame;
frame.origin.y += kbSize.height;
viewDummy.frame = frame;
frame = bubbleTable.frame;
frame.size.height += kbSize.height;
bubbleTable.frame = frame;
}];
}
What i did to get rid of this issue was:
adjusted kbSize.height manually according to difference.
the difference was of height i.e 44 in my case.
so what i did was frame.origin.y += kbSize.height + 44 or
frame.origin.y -= kbSize.height + 44, i think this might help you.
I know that this question is asked many times, but I can not figure out where am I making mistake. In simple words I can not implement it properly.
I have App which has to work on iPhone and iPad (in portrait orientation only). I have a subclassed UITextField. I need to move it up when it is hidden by keyboard during the edit.
I can not set it properly, because the calculation of the size of the keyboard is done after it enters in the edit mode.
I know that I need following steps:
Register observer
Have routine that calculates Keyboard rectangle from which I can take height
Have 2 events on show and hide of the keyboard to make offset of my custom text field.
Please tell me where I am wrong.
My code is:
Register observer:
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardDidShowNotification object:nil];
_leftInlineImage = NO;
}
return self;
}
Calculating keyboard height:
- (void)keyboardWillChange:(NSNotification *)notification {
NSDictionary* d = [notification userInfo];
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
r = [self.superview convertRect:r fromView:nil];
_keyboardHeight = r.size.height;
}
Show/hide keyboard:
/* Move keyboard */
-(void)showKeyboardWithMove {
CGRect screenRect = [[UIScreen mainScreen] bounds];
////CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
//_keyboardHeight = KEYBOARD_HEIGHT;
if (self.frame.origin.y + self.frame.size.height > screenHeight - _keyboardHeight) {
double offset = screenHeight - _keyboardHeight - self.frame.origin.y - self.frame.size.height;
CGRect rect = CGRectMake(0, offset, self.superview.frame.size.width, self.superview.frame.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
self.superview.frame = rect;
[UIView commitAnimations];
}
}
-(void)hideKeyboardWithMove {
CGRect rect = CGRectMake(0, 0, self.superview.frame.size.width, self.superview.frame.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
self.superview.frame = rect;
[UIView commitAnimations];
}
The calculation is made before and my height is 0. All this is done in the subclass of the UITextField.
Add an observer of UIKeyboardWillChangeFrameNotification to the viewDidLoad;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardFrameDidChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
This method will help you :
- (void)keyboardFrameDidChange:(NSNotification *)notification
{
CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
UIViewAnimationCurve animationCurve = [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
NSTimeInterval animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] integerValue];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
CGRect newFrame = self.view.frame;
CGRect keyboardFrameEnd = [self.view convertRect:keyboardEndFrame toView:nil];
CGRect keyboardFrameBegin = [self.view convertRect:keyboardBeginFrame toView:nil];
newFrame.origin.y -= (keyboardFrameBegin.origin.y - keyboardFrameEnd.origin.y);
self.view.frame = newFrame;
[UIView commitAnimations];
}
that gives you back the height of the keyboard.
NSNotification * note = // ... the notification you receive via UIKeyboardWillShowNotification
id _obj = [note.userInfo valueForKey:#"UIKeyboardBoundsUserInfoKey"];
CGRect _keyboardBound = CGRectNull;
if ([_obj respondsToSelector:#selector(getValue:)]) [_obj getValue:&_keyboardBound];
the _keyboardBound will have the correct size.
NOTE: that is not a full implementation to handle the keyboard's appearance, if you need the complex idea, please check my complete and accepted answer here (stackoverflow.com internal link).
I have a message like chat window. When the keyboard was shown, I would push the UITextField so it appears to be right above the keyboard. In iOS 7, it works fine, but it doesn't work on iOS 8. Here's my code
// Detect the keyboard events
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
// Listen to keyboard shown/hidden event and resize.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.2f animations:^{
CGRect frame = self.textInputView.frame;
frame.origin.y -= kbSize.height;
self.textInputView.frame = frame;
frame = self.myTableView.frame;
frame.size.height -= kbSize.height;
self.myTableView.frame = frame;
}];
[self scrollToTheBottom:NO];
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.2f animations:^{
CGRect frame = self.textInputView.frame;
frame.origin.y += kbSize.height;
self.textInputView.frame = frame;
frame = self.myTableView.frame;
frame.size.height += kbSize.height;
self.myTableView.frame = frame;
}];
}
You're using UIKeyboardFrameBeginUserInfoKey, in order for your code to work, you should be using UIKeyboardFrameEndUserInfoKey
UIKeyboardFrameBeginUserInfoKey The key for an NSValue object
containing a CGRect that identifies the start frame of the keyboard in
screen coordinates. These coordinates do not take into account any
rotation factors applied to the window’s contents as a result of
interface orientation changes. Thus, you may need to convert the
rectangle to window coordinates (using the convertRect:fromWindow:
method) or to view coordinates (using the convertRect:fromView:
method) before using it.
UIKeyboardFrameEndUserInfoKey The key for an NSValue object containing
a CGRect that identifies the end frame of the keyboard in screen
coordinates. These coordinates do not take into account any rotation
factors applied to the window’s contents as a result of interface
orientation changes. Thus, you may need to convert the rectangle to
window coordinates (using the convertRect:fromWindow: method) or to
view coordinates (using the convertRect:fromView: method) before using
it.
This worked before ios7 when someone tapped on anything that could become first responder inside a UIScrollView. Now it does not - UITextFields/Views still can show under the keyboard.
Code:
- (void)keyboardWasShown:(NSNotification*)notification{
//Some similar questions mentioned this might work, but made no difference for me
self.automaticallyAdjustsScrollViewInsets=NO;
NSDictionary* info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
float height = 0.0;
if (UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
height = kbSize.width;
} else {
height = kbSize.height;
}
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, height, 0.0);
[UIView animateWithDuration:.25
delay:0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^
{
self.editorScrollView.contentInset = contentInsets;
self.editorScrollView.scrollIndicatorInsets = contentInsets;
}
completion:^(BOOL finished)
{
}];
}
Currently, with this code nothing takes place when a uitextfield/view is assigned first responder status. The insets don't seem to change - I perhaps could use contentOffset but I would have to find the origin view's Y who just become first responder to do that.
Like I said, before ios7 this code worked (no textfield/view would be hidden behind the keyboard when assigned first responder status). I seem to be missing something obvious or perhaps there is a better way of doing this in ios7?
A better way to detect keyboard changing and frame.
The key point is to convert keyboard frame: CGRect keyboardFrameInsideView = [self.view convertRect:keyboardFrame fromView:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardFrameWillChange:)
name:UIKeyboardWillShowNotification
object:nil];
- (void)keyboardFrameWillChange:(NSNotification *)notification
{
CGRect keyboardFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
CGRect keyboardFrameInsideView = [self.view convertRect:keyboardFrame fromView:nil];
CGRect r = self.bodyView.frame;
r.size.height = CGRectGetMinY(keyboardFrameInsideView) - r.origin.y;
self.bodyView.frame = r;
}