title: UIView block animation transitions with animated content on showing/hiding keyboard
body: <p>In my app I have a text field on some view which is covered by the keyboard when it shows up. So I have to scroll the view (or even rearrange the subviews). To do this I:</p>
  
  <ol>
  <li><p>register for keyboard notifications:</p>
  
  <pre><code>[[NSNotificationCenter defaultCenter] addObserver:self
                                        selector:@selector(moveViewUp)
                                        name:UIKeyboardWillShowNotification
                                        object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self
                                        selector:@selector(moveViewDown)
                                        name:UIKeyboardWillHideNotification
                                        object:nil];
  </code></pre></li>
  <li><p>upon receiving a notification, move the view using block animations like this:</p>
  
  <pre><code>- (void)moveViewUp {
      void (^animations)(void) = nil;
      oldViewFrame = self.view.frame;
      animations = ^{
          CGRect newViewFrame = oldViewFrame;
          newViewFrame.origin.y -= kViewOffset;
          self.view.frame = newViewFrame;
      };
      [UIView animateWithDuration:1.0
              animations:animations];
  
  }
  
  - (void)moveViewDown {
      void (^animations)(void) = nil;
      animations = ^{
          self.view.frame = oldViewFrame;
      };
      [UIView animateWithDuration:1.0
              animations:animations];
  
  }
  </code></pre></li>
  </ol>
  
  <p>This works fine, the view scrolls up and down, until I add some more animation. Specifically I'm adding a transition to a next view when the user taps a button:</p>
  
  <pre><code>- (IBAction)switchToNextView:(id)sender {
      // [self presentModalViewController:nextViewController animated:YES];
      [UIView transitionFromView:self.view
                          toView:self.nextView
                        duration:1.0
                         options:UIViewAnimationOptionTransitionFlipFromRight
                      completion:nil];
  }
  </code></pre>
  
  <p>Now we got to the problem.<br>
  If the first view was shifted when the button was tapped (that means that the keyboard was visible), the transition to the next view starts simultaneously as the keyboard slides down, but the view itself <strong>doesn't move down</strong>, so for a split second we can actually see the underlying view. That's not right. When I present the next view modally (see the commented line) all animations go as I want them to: i.e. the keyboard is hiding, the view is flipping from right <em>and</em> scrolling down -- all at the same time. This would be fine, but the problem is that I actually don't have a <code>UIViewController</code> for that view. In fact I'm trying to simulate the modal behavior without <code>UIViewController</code> (why so? <a href="https://stackoverflow.com/questions/5720130/present-login-screen-on-app-startup">perhaps it's just a bad design, I'll post another question on that</a>).  </p>
  
  <p>So why does in this case the animation from <code>moveViewDown</code> method is not triggered at the proper time?</p>
  
  <h2>Update 1</h2>
  
  <p>I added a debug print to each function to check the order of calling, this is what I get:</p>
  
  <pre><code>-[KeyboardAnimationViewController moveViewUp]
  __-[KeyboardAnimationViewController moveViewUp]_block_invoke_1 &lt;-- scroll up animation
  -[KeyboardAnimationViewController switchToNextView:]
  -[KeyboardAnimationViewController moveViewDown]
  __-[KeyboardAnimationViewController moveViewDown]_block_invoke_1 &lt;-- scroll down animation
  </code></pre>
  
  <p>Even if I explicitly move the view down before the transition like this</p>
  
  <pre><code>- (IBAction)switchToNextView:(id)sender {
      // [self presentModalViewController:nextViewController animated:YES];
      NSLog(@"%s", __PRETTY_FUNCTION__);
      if (self.view.frame.origin.x &lt; 0)
          [self moveViewDown];
      [UIView transitionFromView:self.view
                          toView:self.nextView
                        duration:1.0
                         options:UIViewAnimationOptionTransitionFlipFromRight
                      completion:nil];
  }
  </code></pre>
  
  <p>I get <em>exactly</em> the same log.</p>
  
  <h2>Update 2</h2>
  
  <p>I've experimented some more and made following conclusions:</p>
  
  <ol>
  <li>If I call <code>moveViewDown</code> or <code>resignFirstResponder:</code> explicitly, the animation is postponed until the end of current run loop, when all pending animations actually start to play. Though the animation block logs to the console immediately -- <strong>seems strange to me!</strong></li>
  <li>The method <code>transitionFromView:toView:duration:options:completion:</code>  (perhaps <code>transitionWithView:duration:options:animations:completion:</code> too, didn't check this one) apparently makes a snapshot of the "from-view" and the "to-view" and creates an animation using these snapshots solely. Since the scrolling of the view is postponed, the snapshot is made when the view is still offset. The method somehow <strong>disregards even the <code>UIViewAnimationOptionAllowAnimatedContent</code> option</strong>.</li>
  <li>I managed to get the desired effect using any of <code>animateWithDuration: ... completion:</code> methods. These methods seems to <strong>disregard transition options</strong> like <code>UIViewAnimationOptionTransitionFlipFromRight</code>.</li>
  <li>The keyboard starts hiding (implicitly) and sends corresponding notification when <code>removeFromSuperview</code> is called.</li>
  </ol>
  
  <p>Please correct me if I'm wrong somewhere.</p>