I'm trying to animate a UITextField
but I've been caught by a annoying and strange problem. My animation has the following sequence:
In first state the application has the UITextField
, the camera UIButton
and the cancel UIButton
after the camera button that is not been showed because it is been positioned out of the limits of the application. Actually my application has 320 of width and the cancel button origin is (350,7)
In second state, when user touches on UITextField
, the camera button alpha channel is set to 0 and the origin of cancel button is set to (247,7).
The final state is the same as first state after user touched on Return button of keyboard or in cancel button.
During process the UITextField width and the cancel button origin in x axis are animated.
My code is:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = NO;
CGFloat cancelButtonXOffset = CGRectGetMaxX(barcodeSearchButton.frame) - cancelButton.frame.size.width;
CGFloat searchFieldWidth = searchField.frame.size.width - cancelButton.frame.size.width + barcodeSearchButton.frame.size.width;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldWidth, searchField.frame.size.height);
cancelButton.alpha = 1.0;
cancelButton.frame = CGRectMake(cancelButtonXOffset, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 0.0;
}
completion:^(BOOL finished) {
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = YES;
}];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = NO;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldStartWidth, searchField.frame.size.height);
cancelButton.alpha = 0.0;
cancelButton.frame = CGRectMake(cancelButtonStartX, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 1.0;
}
completion:^(BOOL finished) {
barcodeSearchButton.userInteractionEnabled = YES;
cancelButton.userInteractionEnabled = NO;
}];
}
When the animation is executed until the final state ONLY for the first time, which means, user touched on UITextField, WROTE DOWN (this part is important) some text on field and after that the user touched on keyboard return button the problem appears. The problem is that the typed text in UITextField is animated when the width of UITextField is animated too.
The animation behaves like bellow:
UITextField
stretches back to its initial value.UITextField
and it lands into UITextfield
to the position the it should not have gone.The problem is that the step 4 should not happen and the problem is it happens only one time. If a start the process again (touch on uitextfield, type some text, touch on return key) the step 4 does not happen.
I spend a day long trying to solve this problem but I was unsuccessful.
Thanks for answers of everyone but I've found the solution some time ago. The correct way to start an animation in a UITextField
, depending on the keyboard state, is overriding the methods textFieldShouldBeginEditing
and textFieldShouldEndEditing
.
My first attempt I was overriding textFieldDidBeginEditing
and textFieldDidEndEditing
to create the animations. I don't know the reason to the animations work in textFieldShouldBeginEditing
and textFieldShouldEndEditing
but not in textFieldDidBeginEditing
and textFieldDidEndEditing
. But it just works.
My revised code version:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat cancelButtonXOffset = CGRectGetMaxX(barcodeSearchButton.frame) - cancelButton.frame.size.width;
CGFloat searchFieldWidth = searchField.frame.size.width - cancelButton.frame.size.width + barcodeSearchButton.frame.size.width;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldWidth, searchField.frame.size.height);
cancelButton.alpha = 1.0;
cancelButton.frame = CGRectMake(cancelButtonXOffset, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 0.0;
} completion:^(BOOL finished) {
searchField.clearButtonMode = UITextFieldViewModeAlways;
}];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldStartWidth, searchField.frame.size.height);
cancelButton.alpha = 0.0;
cancelButton.frame = CGRectMake(cancelButtonStartX, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 1.0;
} completion:^(BOOL finished) {
searchField.clearButtonMode = UITextFieldViewModeNever;
}];
return YES;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With