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.
Related
I am facing very strange situation. I want to scroll-up the UIScrollView to visible when keyboard appear on some UITextView, and this part of the code is working fine. But when keyboard disappears, scrollView do not come to its original position. When I drag it then it come to its original position. Following is what I have done. Please guide me what I have missed
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary* info = [notification userInfo];
kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect commentViewFrame = self.detailCommentView.frame;
commentViewFrame.origin.y += kbSize.height;
[UIView animateWithDuration:0.3 animations:^{
[self.detailCommentView setFrame:commentViewFrame];
self.scrollView.contentOffset = CGPointMake(0, self.detailCommentView.frame.origin.y - 90);
} completion:^(BOOL finished) {
}];
}
- (void)keyboardWillShow:(NSNotification *)notification {
NSDictionary* info = [notification userInfo];
kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect commentViewFrame = self.detailCommentView.frame;
commentViewFrame.origin.y -= kbSize.height;
[UIView animateWithDuration:0.3 animations:^{
[self.detailCommentView setFrame:commentViewFrame];
self.scrollView.contentOffset = CGPointMake(0, self.detailCommentView.frame.origin.y + 90);
} completion:^(BOOL finished) {
}];
}
I'd blindly try using UIKeyboardFrameEndUserInfoKey instead of UIKeyboardFrameBeginUserInfoKey to see if it works.
Otherwise I'd check whether commentViewFrame value is correct when you're hiding the keyboard.
There is also one more thing that I don't know whether is correct. In keyboardWillShow you're referencing self.detailCommentView.frame.origin.y but in keyboardWillHide you're referencing self.dopDetailCommentView.frame.origin.y. Is it alright?
I have found the solution. Actually the concept behind scrollview was not clear to me. But now it is clear and change in one line only made the trick.
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary* info = [notification userInfo];
kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect commentViewFrame = self.detailCommentView.frame;
commentViewFrame.origin.y += kbSize.height;
[UIView animateWithDuration:0.3 animations:^{
[self.detailCommentView setFrame:commentViewFrame];
self.scrollView.contentOffset = CGPointMake(0, 0);
} completion:^(BOOL finished) {
}];
}
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 using a UIKeyboardWillShowNotification to know when the keyboard is shown and adjust the size of my UIWebView so that it isn't hidden behind the keyboard.
The strange thing is, when I change the frame in the method that gets called by NSNotificationCenter it changes the frame in a way that lets me scroll my UIWebView content (red in screenshot), but also a large portion of the UIWebView scrolls into view (yellow in screenshot). The yellow should never be shown.
- (void)keyboardWillShowOrHide:(NSNotification *)notification {
// User Info
NSDictionary *info = notification.userInfo;
CGFloat duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
int curve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboard = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) {
[UIView animateWithDuration:duration delay:0 options:curve animations:^{
CGRect frame = self.toolbarHolder.frame;
frame.origin.y = (self.view.frame.size.height - keyboard.size.height) - 44;
self.toolbarHolder.frame = frame;
// Editor View
CGRect editorFrame = self.editorView.frame;
editorFrame.size.height = (self.view.frame.size.height - keyboard.size.height) - 44;
self.editorView.frame = editorFrame;
} completion:nil];
} else {
[UIView animateWithDuration:duration delay:0 options:curve animations:^{
CGRect frame = self.toolbarHolder.frame;
frame.origin.y = self.view.frame.size.height;
self.toolbarHolder.frame = frame;
// Editor View
CGRect editorFrame = self.editorView.frame;
editorFrame.size.height = self.view.frame.size.height;
self.editorView.frame = editorFrame;
} completion:nil];
}
}
If I change the UIWebView frame in a different method than the one called from NSNotificationCenter, the frame changes correctly and the area above the keyboard is only filled with my HTML content within the UIWebView (red).
What could be causing this issue?
Use UIKeyboardFrameEndUserInfoKey key that returns the final expected frame for keyboard
Hello i am facing a problem with UITextView.
In my app , i need to support both Portrait and Landscape.
So i added UITextView into my app and resize the frame of UITextView when keyboard appearing with following code because when keyboard appear , the UITextView is behind the keyboard and i can't see what i write in UITextView.
- (void)keyboardWillShow:(NSNotification*)notification
{
[self moveTextViewForKeyboard:notification up:YES];
}
- (void)keyboardWillHide:(NSNotification*)notification
{
[self moveTextViewForKeyboard:notification up:NO];
}
- (void)moveTextViewForKeyboard:(NSNotification*)notification up:(BOOL)up {
NSDictionary *userInfo = [notification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardRect;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
keyboardRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
if (up == YES)
{
CGFloat keyboardTop = keyboardRect.origin.y;
CGRect newTextViewFrame = self.txtView.frame;
newTextViewFrame.size.height = keyboardTop - self.txtView.frame.origin.y - 10;
self.txtView.frame = newTextViewFrame;
}
else
{
self.txtView.frame = originalCGRect;
}
[UIView commitAnimations];
}
That is fine when keyboard appear and not covering my UITextView anymore.
However when i rotate into Landscape , the UITextView frame is not correct anymore and also when i hide keyboard , it still remain like small size and not the fit with View.
How can i solve that problem?
Please help me.
Try this i hope helpful to you....
I have the following interface layout on my application:
When I click on a text field (if you lick add tag a new text field is added) I make my view scroll up as to not be obstructed by the keyboard so the user can properly see what he's typing, but the following happens when I do so:
This is the code I use to scroll:
- (void)keyboardWillShow:(NSNotification *)notification {
if (self.keyboardIsShown) {
return;
}
NSValue *keyboardBoundsValue = [[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [keyboardBoundsValue CGRectValue].size;
NSTimeInterval animationDuration = 0.3;
CGRect frame = self.view.frame;
frame.origin.y -= keyboardSize.height - 94 + self.firstResponder.superview.superview.frame.origin.y;
frame.size.height += keyboardSize.height - 94 + self.firstResponder.superview.superview.frame.origin.y;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
self.keyboardIsShown = YES;
}
- (void)keyboardWillHide:(NSNotification *)notification {
NSValue *keyboardBoundsValue = [[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [keyboardBoundsValue CGRectValue].size;
NSTimeInterval animationDuration = 0.3;
CGRect frame = self.view.frame;
frame.origin.y += keyboardSize.height - 94 + self.firstResponder.superview.superview.frame.origin.y;
frame.size.height -= keyboardSize.height - 94 + self.firstResponder.superview.superview.frame.origin.y;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
self.keyboardIsShown = NO;
}
Any idea how I can make the view elements show behind the navbar or disappear or another workaround that would work properly?
A quick way to achieve what you want, would be to have your navigation bar below the "content"-view in your view tree. That way the navigation bar will remain on top. If you add the content dynamically. Make sure you add them as subviews of a view that is behind the navigation bar.
// Edit
As proposed in the comments:
self.view.clipsToBounds = YES;
CGRect frame = self.yourWrappingView.frame;
NSUInteger distanceToMove = 200;
self.yourWrappingView.frame = CGRectMake(frame.origin.x - distanceToMove, frame.origin.y, frame.size.width, frame.size.height);
This should work for you mate :)
Probably you are not using a real UINavigationController. But you should. So you wouldn't have those problems and a correct resizing behaviour. But to solve it in your current architecture:
Make sure the Navigation Bar is the top most object in your nib file / storyboard
add an IBOutlet for your UINavigationBar and if you insert new views dynamically, use [self insertSubview: newView belowSubview: navigationBarOutlet];