1

I have a view with 1. Navigation bar 2.UITableView 3. UITextView.

When I start to edit the textView, a keyboard comes up and I need to animate the TextView and TableView up. I've implemented: https://stackoverflow.com/a/8704371/1808179, but that animated the entire view up, covering the navigation bar.

I tried individually animating the textView like:

- (void)keyboardWillShow:(NSNotification*)notification
{
    CGRect chatTextFieldFrame = CGRectMake(chatTextField.frame.origin.x,chatTextField.frame.origin.y-218,chatTextField.frame.size.width,chatTextField.frame.size.height);
    [UIView animateWithDuration:0.5 animations:^{ chatTextField.frame = chatTextFieldFrame;}];
}

But it doesn't animate, and it won't synchronously animate alongside the TableView.

What is the best way to animate the tableView and textView up without overlaying the navigation bar?

Community
  • 1
  • 1
Spenciefy
  • 892
  • 11
  • 33

3 Answers3

7

I generally use the follow snippet when tackling this problem.

Using a UITableView (which is just a subclass of UIScrollView) you should set contentInsets rather then just changing the frame each time. This is especially much nicer in iOS7 with a translucent keyboard.

- (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)dealloc;
{
  [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
  [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

#pragma mark - Keyboard Notifications

- (void)keyboardWillShow:(NSNotification *)notification;
{
  NSDictionary *userInfo = [notification userInfo];
  NSValue *keyboardBoundsValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
  CGFloat keyboardHeight = [keyboardBoundsValue CGRectValue].size.height;

  CGFloat duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
  NSInteger animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
  UIEdgeInsets insets = [[self tableView] contentInset];
  [UIView animateWithDuration:duration delay:0. options:animationCurve animations:^{
    [[self tableView] setContentInset:UIEdgeInsetsMake(insets.top, insets.left, keyboardHeight, insets.right)];
    [[self view] layoutIfNeeded];
  } completion:nil];
}

- (void)keyboardWillHide:(NSNotification *)notification;
{
  NSDictionary *userInfo = [notification userInfo];
  CGFloat duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
  NSInteger animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
  UIEdgeInsets insets = [[self tableView] contentInset];
  [UIView animateWithDuration:duration delay:0. options:animationCurve animations:^{
    [[self tableView] setContentInset:UIEdgeInsetsMake(insets.top, insets.left, 0., insets.right)];
    [[self view] layoutIfNeeded];
  } completion:nil];
}
petehare
  • 1,874
  • 16
  • 14
  • How should I deal with the TextField? – Spenciefy Feb 16 '14 at 09:46
  • I think in the table view actually scrolls it up automatically, am I right? If not you could grab the frame of it and manually call `scrollToRect` on the tableView. – petehare Feb 16 '14 at 09:52
  • The textView is separate from the tableView- it's under – Spenciefy Feb 16 '14 at 09:53
  • Note that this will only work reliably in portrait and only if the tableView frame stretches to the bottom of the screen. See my gist for a more robust way to deal with the frame - https://gist.github.com/TimMedcalf/9505416 – TimMedcalf Mar 14 '14 at 05:49
  • This is a great solution but animation happens not synchronously. I mean keyboard's velocity differs from textField velocity – fnc12 Aug 24 '14 at 16:37
0

If any are wondering, this is how I did it:

- (void)keyboardWillShow:(NSNotification*)notification
{
    CGRect chatTableViewFrame = CGRectMake(0,65,320,chatTableView.frame.size.height-180);
    [UIView animateWithDuration:0.3 animations:^{ chatTableView.frame = chatTableViewFrame;}];

    CGRect chatTextFieldFrame = CGRectMake(chatTextField.frame.origin.x,chatTextField.frame.origin.y-170,chatTextField.frame.size.width,chatTextField.frame.size.height);
    [UIView animateWithDuration:0.3 animations:^{ chatTextField.frame = chatTextFieldFrame;}];


    [self.chatTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.chat.count-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

And vice-versa for keyboardWillHide.

Spenciefy
  • 892
  • 11
  • 33
-1

Write this line at desired events.

self.view.frame = [[UIScreen mainScreen] applicationFrame];
jeet.chanchawat
  • 5,842
  • 5
  • 38
  • 59