The iPhone’s keyboard takes up a whopping 216px, and sometimes text fields are positioned towards the bottom. When the keyboard appears, they are hidden.
This article shows how to add a scroll animation to your UIView that scrolls up when the text field is active, and scrolls back to normal when the text field is no longer active.
Note that the keyboards have custom toolbars, which you can learn about here. The "Done" button dismisses the keyboard.
I have defined two values for readability.
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat ANIMATE_VIEW_PADDING = 10;
First, let’s write a generalized method that animates to any Y value:
- -
(void) animateViewToYValue: (float) pixels {
CGRect viewFrame = self.view.frame;
viewFrame.origin.y = pixels;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:.3];
[UIView setAnimationDelay:0];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
NSLog(@"frame origin y %f",self.view.frame.origin.y);
<li>}</li>
On line 1. we copy the existing frame of the view, and on line 2. we change the y value of the origin component to that frame. We now have a frame to animate to with all values exactly like the original frame except the value we are animating (the y value). Line 4 tells the system that we are now going to specify animations to perform. Notice this is a class method to UIView, not to the instance you’re working with. Next, we set some simple values regarding the animation. Then we change the frame of our view to the one we altered earlier, and then commit the animations. I am also logging a message for debug purposes.
So that gives us a generalized animation, but what values do I pass it? Let’s write another helper method, -(void) animateViewToShow: (CGRect) frame; that we can pass a frame, and that method will calculate the value to animate to.
- -
(void) animateViewToShow: (CGRect) frame {
float bottom = frame.origin.y + frame.size.height + ANIMATE_VIEW_PADDING;
float frameKeyboardDifference = bottom – PORTRAIT_KEYBOARD_HEIGHT;
[self animateViewToYValue:-frameKeyboardDifference];
}
On line 2. we calculate the bottom of the frame, because the x,y, coordinate system begins at the upper-left corner. A little padding is added for aesthetics. On line 3. we find the difference between the frame and the keyboard, because this is the amount we will actually want to move! If the text field is 40 pixels below the top of the keyboard, we want to move up 40 px. Finally, on line 4. we can call the method we wrote earlier. However, notice that it is negative. This is because the coordinate system begins at the upper left hand corner, and a negative y coordinate is actually above the origin.
This sets up our animation, but when should we call this method? Well, if our current class is the delegate of the text fields, we will get a call to -(void)textFieldDidBeginEditing:(UITextField *)textField;
when any text field begins editing. Here is the code I use:
- -
(void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField.frame.origin.y > (PORTRAIT_KEYBOARD_HEIGHT – textField.frame.size.height – ANIMATE_VIEW_PADDING)) {
<li><code>[self animateViewToShow:textField.frame];
}
}
On line 2, we check if the text field will be obscured by the keyboard. We just need to check if the keyboard height minus the height of the text field, minus a little padding (so it will move if the text field is within 10px of the keyboard) is less than the position of the text field. In the example, you’ll notice that the top text field doesn’t move, which is what we want. Then, we can send the frame to our helper method, which then calls the animation.
The last thing to do is to animate back to 0px whenever the text field is no longer in use. In the example project it happens when the "Done" button is pressed. Pretty simple!
Here is the example Xcode project if you want to check it out!
The post Simple UIView Vertical Scroll Animation appeared first on Code and Prose.