动画UITextField时的奇怪行为

时间:2011-11-10 22:44:04

标签: ios objective-c xcode ios4 uiviewanimation

我正试图为UITextField设置动画,但我遇到了一个令人烦恼和奇怪的问题。我的动画有以下顺序:

first state

在第一个状态中,应用程序具有UITextField,相机UIButton和取消UIButton之后未显示相机按钮,因为它位于超出限制范围内应用程序。实际上我的应用程序有320的宽度和取消按钮来源是(350,7)

second state

在第二种状态下,当用户触摸UITextField时,相机按钮alpha通道设置为0,取消按钮的原点设置为(247,7)。

final state

用户触摸键盘的返回按钮或取消按钮后,最终状态与第一状态相同。

在处理过程中,UITextField宽度和x轴上的取消按钮原点被设置为动画。

我的代码是:

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

当动画执行到第一次的最终状态时,这意味着,用户触摸了UITextField,WROTE DOWN(这部分很重要)字段上的一些文字,之后用户触摸键盘返回按钮问题出现。问题是,当UITextField的宽度也被动画化时,UITextField中的类型文本也会被动画化。

动画的行为如下:

  1. UITextField延伸回其初始值。
  2. 取消按钮返回其初始原点
  3. 相机按钮设为1.0
  4. 输入的文字从UITextField的左上角飞过,然后落入UITextfield到不应该离开的位置。
  5. 问题是第4步不应该发生,问题是它只发生一次。如果再次启动该过程(触摸uitextfield,键入一些文本,触摸返回键),则步骤4不会发生。

    我花了一天时间试图解决这个问题,但我没有成功。

3 个答案:

答案 0 :(得分:6)

感谢大家的回答,但我前段时间找到了解决方案。根据键盘状态,在UITextField中启动动画的正确方法是覆盖方法textFieldShouldBeginEditingtextFieldShouldEndEditing

我的第一次尝试是覆盖textFieldDidBeginEditingtextFieldDidEndEditing来制作动画。我不知道动画在textFieldShouldBeginEditingtextFieldShouldEndEditing中工作的原因,但不在textFieldDidBeginEditingtextFieldDidEndEditing中。但它只是有效。

我修改后的代码版本:

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

答案 1 :(得分:0)

在搜索字段上设置一些占位符文字, _searchField.text = @“占位符”

并设置 _searchField.clearsOnBeginEditing = YES;

或者您可以清除值,如果它等于您的占位符文本 在textDidBeginEditing

答案 2 :(得分:0)

{已编辑以改进修复} 我有这个完全相同的问题,还有一些进一步的细节,以及一个确实为我修复它的小黑客。

首先是进一步的细节:

  1. 问题仅在帧动画第一次展开时发生 UITextField并在字段中输入了文本。如果 再次编辑UITextField,再次发生相同的动画, 问题不会发生。
  2. searchField.clearsOnBeginEditing = YES;无法解决问题。
  3. 我一直在使用占位符文本整个问题 被观察到了。它对结果没有影响。
  4. 更改1帧的文本属性确实可以解决问题。
  5. 以下是我要解决的问题:

    在我的viewDidLoad我将text属性设置为单个空格,然后将赋值分配给空字符串。

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

    然后在缩小和展开UITextField的方法中,以及在屏幕上移动取消按钮,我检查这是否是瞬时动画并将持续时间设置为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);
        }];
    }
    

    这完全解决了我的情况。