UITableView slightly goes up when keyboard hides - ios

I am using UITableView (chatTable) along with UITabBar (chatTabBar) and one textField inside imageView. I am using autolayout. I used the following code to change the views when keyboard appears and disappears.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
// get animation info from userInfo
NSTimeInterval animationDuration;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
// resize the frame
[UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.keyboardHeight.constant = keyboardFrame.size.height - TABBAR_HEIGHT ;
[self.view layoutIfNeeded];
} completion:nil];
if ([chatData count] != VALUE_ZERO)
{
[chatTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([chatData count] - VALUE_ONE) inSection:VALUE_ZERO] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
}
- (void)keyboardWillHide:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
// get animation info from userInfo
NSTimeInterval animationDuration;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
// Set view frame
[UIView animateWithDuration:animationDuration delay:2.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.keyboardHeight.constant -= keyboardFrame.size.height - TABBAR_HEIGHT;
[self.view layoutIfNeeded];
} completion:nil];
}
Now when I press return the tableview goes up a littel bit (from screen 2 to screen 3). keyboardHeight is the bottom space constraint between the tabBar and main view.
(screen 2)
(screen3)
I have tried many things but I can't able to find why the tableview is going up for a while. (problem is there is no smooth animation.) (Note: I have put delay as 2.0 only to show what happens in following screenshot(screen 3) othewise it's value would be 0)

Your problem is that you're changing the table view frame when the keyboard appears, which is wrong. You need to change the contentInset property of the table view, instead of meddling with frames.
- (void)keyboardWillShow:(NSNotification *)notification {
CGFloat height = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height - self.tabBarController.tabBar.frame.size.height;
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0.0f, 0.0f, height, 0.0f);
_tableView.contentInset = edgeInsets;
_tableView.scrollIndicatorInsets = edgeInsets;
}
- (void)keyboardWillHide:(NSNotification *)notification {
UIEdgeInsets edgeInsets = UIEdgeInsetsZero;
_tableView.contentInset = edgeInsets;
_tableView.scrollIndicatorInsets = edgeInsets;
}

Solved the problem with contentInset property. I am using contentInset as mentiond by the #Eugene and also changing the constant property of bottom constraint of the textfiled to move up and doen whenever keyboard is shown and hidden.

Related

UIScrollView do not scroll down to its original position when keyboard disappear

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) {
}];
}

Textview Frame is become squeez and cannot come back to its original form?

keyboardWillShow method implementation :
- (void)keyboardWillShow:(NSNotification *)notification
{
[UIView beginAnimations:nil context:nil];
CGRect endRect = [[notification.userInfo
objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect newRect = txtNotes.frame;
//Down size your text view
newRect.size.height -= endRect.size.height;
txtNotes.frame = newRect;
[UIView commitAnimations];
}
keyboardWillHide method implementation :
- (void)keyboardWillHide:(NSNotification *)notification
{
// Resize your textview when keyboard is going to hide
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
txtNotes.contentInset = contentInsets;
txtNotes.scrollIndicatorInsets = contentInsets;
}
Couple of things:
1) META: You should add 4 spaces before each of the code lines to get the code to display properly.
2) This looks like a basic constraints issue. You should examine the Auto Layout of your storyboard.

contentInset being ignored in ios7 for UIScrollView

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;
}

UIKeyboardWillShowNotification incorrectly changes frame of UIWebView

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

Resize UITextView when rotation in iOS

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....

Resources