title: iOS UITableView contentOffset when keyboard is shown
body: <p>I am trying to set the <code>contentOffset</code> of a <code>tableView</code> when the <code>keyboard</code> is presented. The actual code is inside a <code>CustomTableView : UITableView &lt;UIScrollViewDelegate&gt;</code>, as it is used widely throughout the app, hence the use of <code>self</code> as the <code>tableView</code>.
  My code looks like this:</p>
  
  <pre><code>- (void)keyboadDidAppear:(NSNotification *)notification {
      NSTimeInterval animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
      CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
      CGFloat keyboardHeight = CGRectGetHeight(keyboardBeginFrame);
      CGPoint contentOffset = self.contentOffset;
      originalContentOffset = self.contentOffset;//hold reference to reset it when keyboard is hidden
      contentOffset.y += keyboardHeight;
      [UIView animateWithDuration:animationDuration animations:^{
          [self layoutIfNeeded];
      } completion:^(BOOL finished) {
          if (finished) {
              [self setContentOffset:contentOffset animated:YES];
          }
      }];
  }
  </code></pre>
  
  <p>The problem is that, it always offsets the content by the keyboard's height, which is wrong, when the user taps a <code>tableCell</code> that is near the top of the <code>tableView</code>. 
  Ideally, I would want to offset the content so the tapped <code>tableCell</code> is just above the keyboard.
  The problem is that I don't know how to do it. I have a rough idea that I would need something like:</p>
  
  <pre><code>distanceBetweenTappedCellAndTableBottom &gt; keyboardHeight ? do nothing : offsetContentBy keyboardHeight + tappedCellHeight.
  </code></pre>
  
  <p>Any suggestions on how could I come up with the numbers? or is there a better solution?</p>
  
  <p>Later edit:</p>
  
  <p>I can't use the <code>contentInset</code> as the <code>tableView</code> has <code>sectionHeaders</code>, and setting the <code>contentInset</code> causes the <code>sectionHeaders</code> to stay fixes, while the <code>rows</code> move up.</p>
  
  <p><strong>Solution</strong> based  on suggestions below:</p>
  
  <pre><code>CGSize kbSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
      NSTimeInterval duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  
      CGFloat height = UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? kbSize.width : kbSize.height;
  
      height += 10.0;//it needs to be slightly higher so the textField is clearly visible.
      originalEdgeInset = self.contentInset;
      __weak typeof (self) block = self;
      [UIView animateWithDuration:duration animations:^{
          UIEdgeInsets edgeInsets = block.contentInset;
          edgeInsets.bottom += height;
          block.contentInset = edgeInsets;
          edgeInsets = block.scrollIndicatorInsets;
          edgeInsets.bottom += height;
          block.scrollIndicatorInsets = edgeInsets;
      }];
  </code></pre>