Strange behavior when animating UITextField

限于喜欢 提交于 2019-12-05 11:32:21
Fabio

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;
}

Set some placeholder text on the search field, _searchField.text = @"placeholder"

and also set _searchField.clearsOnBeginEditing = YES;

Or you can just clear out the value if it's equal to your placeholder text on textDidBeginEditing

Kurt Arnlund

{edited to improve the fix} I have this exact same problem, and some further details as well as a small hack that is indeed fixing it for me.

So first the further details:

  1. The problem only occurs the first time the frame animation expands the UITextField and there is entered text in the field. If the UITextField is edited again, and the same animations happen again, the problem does not happen.
  2. searchField.clearsOnBeginEditing = YES; does not clear the problem.
  3. I've been using placeholder text the entire time the problem has been observed. It has no effect on the results.
  4. Changing the text property for 1 frame does have the effect of clearing the problem.

Here is what I am doing to fix it:

In my viewDidLoad I am setting the text property to a single space, then dispatching once an assignment to an empty string.

-(void)viewDidLoad {
    searchField.text = @" ";
    dispatch_async(dispatch_get_main_queue(), ^{
        searchField.text = @"";
    });
}

Then in my methods that shrink and expand the UITextField, as well as move a cancel button on-screen, I check if this is an instantaneous animation and set the duration to 0.0f.

- (void)showCancelButton {
    NSTimeInterval duration = 0.3f;

    [UIView animateWithDuration:duration animations:^{ 
        CGPoint buttonOrigin = cancelButton.frame.origin;
        CGSize buttonSize = cancelButton.frame.size;
        CGFloat buttonTravelDist = buttonSize.width + 10.0f;
        CGPoint onscreenPos = CGPointMake(buttonOrigin.x - buttonTravelDist, buttonOrigin.y);

        cancelButton.frame = CGRectMake(onscreenPos.x, onscreenPos.y, buttonSize.width, buttonSize.height);

        CGPoint fieldOrigin = searchField.frame.origin;
        CGSize fieldSize = searchField.frame.size;

        searchField.frame = CGRectMake(fieldOrigin.x, fieldOrigin.y, fieldSize.width - buttonTravelDist, fieldSize.height);
    }];
}

- (void)hideCancelButton {
    NSTimeInterval duration = 0.3f;

    [UIView animateWithDuration:duration animations:^{ 
        CGPoint buttonOrigin = cancelButton.frame.origin;
        CGSize buttonSize = cancelButton.frame.size;
        CGFloat buttonTravelDist = buttonSize.width + 10.0f;
        CGPoint onscreenPos = CGPointMake(buttonOrigin.x + buttonTravelDist, buttonOrigin.y);

        cancelButton.frame = CGRectMake(onscreenPos.x, onscreenPos.y, buttonSize.width, buttonSize.height);

        CGPoint fieldOrigin = searchField.frame.origin;
        CGSize fieldSize = searchField.frame.size;

        searchField.frame = CGRectMake(fieldOrigin.x, fieldOrigin.y, fieldSize.width + buttonTravelDist, fieldSize.height);
    }];
}

This has completely fixed the situation for me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!