title: Move view when jumping from text field to text field
body: <p>I have a form with a few text fields on a scroll view. I was trying to solve the problem of the keyboard hiding some text fields, which I partly did. At least it works well when I tap on each individual field. I used the recommended Apple approach:</p>
  
  <p>I have registered for keyboard notifications in viewDidLoad:</p>
  
  <pre><code>[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:self.view.window];                                       
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:self.view.window];
  </code></pre>
  
  <p>I am tracking active text fields:</p>
  
  <pre><code>- (void)textFieldDidBeginEditing:(UITextField *)textField {
      activeTextField = textField;
  }
  
  - (void)textFieldDidEndEditing:(UITextField *)textField {
      activeTextField = nil;
  }
  </code></pre>
  
  <p>I am scrolling the view up when the keyboard shows up:</p>
  
  <pre><code>- (void)keyboardWillShow:(NSNotification *)aNotification {
      // Get the size of the keyboard
      NSDictionary* info = [aNotification userInfo];
      keyboardHeight = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;
  
      UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardHeight, 0.0);
      scrollView.contentInset = contentInsets;
      scrollView.scrollIndicatorInsets = contentInsets;
  
      // If active text field is hidden by keyboard, scroll it so it's visible
      CGRect aRect = self.view.frame;
      aRect.size.height -= keyboardHeight + 44 + 44; // Compensates for Navbar and text field height
      if (!CGRectContainsPoint(aRect, activeTextField.frame.origin) ) {
          [scrollView scrollRectToVisible:activeTextField.frame animated:YES];
      }
  }
  </code></pre>
  
  <p>I then scroll the view back to default when the keyboard is hidden (I won't paste the code simply because it works fine).</p>
  
  <p>However, out of my 5 text fields, the first 4 have a Next button on the keyboard (instead or Return) while the last field has Done. The idea is that I want the user to jump from one text field to another (in one direction is enough in my case). So, I've implemented a UITextField delegate method to handle that as well:</p>
  
  <pre><code>- (BOOL)textFieldShouldReturn:(UITextField *)textField {
      if (textField == firstNameTextField) {
          [lastNameTextField becomeFirstResponder];
  
      } else if (textField == lastNameTextField) {
          [countryTextField becomeFirstResponder];
  
      } else if (textField == cityTextField) {
          [zipCodeTextField becomeFirstResponder];
  
      } else if (textField == zipCodeTextField) {
          [zipCodeTextField resignFirstResponder];
      }
      return NO;
  }
  </code></pre>
  
  <p>The middle text field above is skipped, because for that text field I'm using a different input type (a custom view with a UIPickerView and a bar on top with Next button) - the missing code is in this method:</p>
  
  <pre><code>- (IBAction)goToNextTextField:(id)sender {
      [cityTextField becomeFirstResponder];
  }
  </code></pre>
  
  <p>OK, as I've mentioned, view adjustment works well when tapping individual text fields (and then dismissing the keyboard), even though keyboard sizes (standard iOS vs my custom view) are different heights. I can also successfully go through all text fields tapping on Next buttons.</p>
  
  <p>Here are my issues though:</p>
  
  <ul>
  <li>When tapping on Next, if the keyboard is not changing (say, from field 4 to 5 that both use standard keyboard), my keyboardWillShow: method is not called, NSLog debugger shows keyboardHeight as 0, and yet the view moves up unpredictably.</li>
  <li>Also, when navigating to and from field 3 (the one that uses custom input view), keyboardHeight is thus not recalculated. I have tried registering to UIKeyboardDidChangeFrameNotification and UIKeyboardWillChangeFrameNotification (pointing to keyboardWillShow: method), but without much success. It is worth noting that I do see in console that keyboardHeight is changing, but it's usually lagging one step, i.e. keyboardHeight is updated when I leave the field, not when it becomeFirstResponder.</li>
  </ul>
  
  <p>Perhaps a pair of experienced eyes will spot my mistake, for I have been destroying my pair of eyes searching for the solution for the last 2 days..</p>
  
  <p>Thanks!</p>