1
[UIView animateWithDuration:0.6 delay:0.0 options:UIViewAnimationCurveLinear animations:^{
    [self.searchField becomeFirstResponder];
} completion:nil];

animates the keyboard entry by having it appear as if its far away and in the top left corner of the screen, swinging inward in a slightly curved line to it's final resting spot. This happens no matter what UIView animation method I use.

Even stranger, it only happens once. Not just once per view controller, but ONCE, period. Dispatch_once style.

The effect I'm looking for (which works all subsequent times my method is called, and works for [self.view endEditing]) is just a standard linear entry every time. I need this inside an animation block to keep it on the same time schedule as an animation I have that slides down my searchField from under the status bar.

My question - How can I guarantee consistent animation of [viewObject becomeFirstResponder] inside UIView animation blocks?

user
  • 3,388
  • 7
  • 33
  • 67

2 Answers2

1

The reason the keyboard comes from the top left corner the first time you animate it is because it's initial position and size is (0,0,0,0). So on first creation (the first animation block) it animates from (0,0,0,0) to whatever the frame is when it is visible on screen. Subsequent calls to that animation will show the keyboard in the right initial position and then animate properly.

In my research I found someone say it is very bad practice to put Apple built in animations inside your animation blocks, and I agree.

The way to get around this is to listen for keyboard motion, get the properties from the keyboard Apple defined animation and do your animating with the same properties. Something like this from this answer:

Setup your keyboard listening:

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:UIKeyboardWillShowNotification 
                                                  object:nil]; 
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:UIKeyboardWillHideNotification 
                                                  object:nil];  

}

- (void)dealloc {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:UIKeyboardWillShowNotification 
                                                  object:nil]; 
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:UIKeyboardWillHideNotification 
                                                  object:nil];  

}

And then setup the functions to mimick they keyboard animation properties:

- (void)keyboardWillHide:(NSNotification *)n
{
    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;


    // resize the scrollview
    CGRect viewFrame = self.scrollView.frame;
    // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
    viewFrame.size.height += (keyboardSize.height - kTabBarHeight);

    NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];



    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:animationDuration];
    //Your animations go here
    [UIView commitAnimations];

    keyboardIsShown = NO;
}

You should be able to extract what you need from these bits of code and make your app look exactly like you would like it to. Good luck.

Community
  • 1
  • 1
Putz1103
  • 6,211
  • 1
  • 18
  • 25
1

You can use the values for UIKeyboardAnimationCurveUserInfoKey and UIKeyboardAnimationDurationUserInfoKey keys of userInfo property from UIKeyboardWillShowNotification to synchronize your animation with the keyboard animation.

cahn
  • 1,350
  • 1
  • 12
  • 24