2011-11-10 12 views
5

Estoy tratando de animar un UITextField pero me ha atrapado un problema molesto y extraño. Mi animación tiene la siguiente secuencia:Comportamiento extraño al animar UITextField

first state

En primer estado de la aplicación tiene la UITextField, la cámara UIButton y cancelar UIButton después de que el botón de la cámara que no se ha mostró porque se ha colocado fuera de los límites de la aplicación. En realidad mi aplicación tiene 320 de anchura y el origen cancelar botón es (350,7)

second state

En segundo estado, cuando toques de usuario en UITextField, el botón canal alfa de la cámara se establece en 0 y el origen de botón de cancelación está establecido en (247,7).

final state

El estado final es el mismo que el botón primer estado cuando el usuario toca el botón de retorno del teclado o de cancelar.

Durante el proceso, se animan el ancho de UITextField y el origen del botón cancelar en el eje x.

Mi código es:

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

Cuando la animación se ejecuta hasta que el estado final SOLAMENTE por primera vez, lo que significa, el usuario se refirió a UITextField, anotaba (esta parte es importante) un texto sobre el terreno y luego de que el usuario tocó el botón de retorno del teclado, aparece el problema. El problema es que el texto escrito en UITextField está animado cuando el ancho de UITextField está animado también.

La animación se comporta como abajo:

  1. Los UITextField tramos de nuevo a su valor inicial.
  2. Cancelar espaldas de botón a su origen inicial
  3. botón de la cámara se ajusta a 1,0
  4. El texto escrito vuela desde la esquina superior izquierda de UITextField y aterriza en UITextfield a la posición de la que no debería haber ido.

El problema es que el paso 4 no debería ocurrir y el problema es que ocurre una sola vez. Si comienza nuevamente el proceso (toque en uitextfield, escriba algo de texto, toque en la tecla de retorno) el paso 4 no ocurre.

Paso un día tratando de resolver este problema pero no tuve éxito.

Respuesta

0

Establecer un texto de marcador de posición en el campo de búsqueda, _searchField.text = @ "marcador de posición"

y también establecer _searchField.clearsOnBeginEditing = SÍ;

o simplemente puede limpiar el valor si es igual a su texto marcador de posición en textDidBeginEditing

+0

Además, el uso de texto en lugar de la propiedad de texto de marcador de posición puede meterse con sus colores, por lo que tendrá que arreglar eso para arriba también. –

0

{editado para mejorar el arreglo} tengo este mismo problema, y ​​algunos detalles adicionales, así como una pequeña hack que de hecho lo está arreglando para mí.

Así que primero los detalles:

  1. El problema sólo se produce la primera vez que la animación fotograma expande la UITextField y no se introduce texto en el campo. Si el UITextField se edita de nuevo, y las mismas animaciones vuelven a ocurrir, el problema no ocurre.
  2. searchField.clearsOnBeginEditing = YES; no soluciona el problema.
  3. He estado usando texto de marcador de posición todo el tiempo que se ha observado el problema . No tiene ningún efecto en los resultados.
  4. Cambiar la propiedad del texto para 1 fotograma tiene el efecto de solucionar el problema.

Esto es lo que estoy haciendo para solucionarlo:

En mi viewDidLoad estoy fijando la propiedad de texto a un solo espacio, entonces el envío de una vez una asignación a una cadena vacía.

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

Luego, en mis métodos que se encogen y expanden el UITextField, así como mover un botón cancelar en la pantalla, puedo comprobar si se trata de una animación instantánea y establecer la duración de 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); 
    }]; 
} 

Esto me ha solucionado completamente la situación.

6

Gracias por las respuestas de todos pero he encontrado la solución hace algún tiempo. La forma correcta de iniciar una animación en UITextField, según el estado del teclado, es anular los métodos textFieldShouldBeginEditing y textFieldShouldEndEditing.

Mi primer intento estaba sobreescribiendo textFieldDidBeginEditing y textFieldDidEndEditing para crear las animaciones. No sé el motivo de las animaciones que funcionan en textFieldShouldBeginEditing y textFieldShouldEndEditing pero no en textFieldDidBeginEditing y textFieldDidEndEditing. Pero solo funciona.

Mi versión de código revisado:

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

Esto funciona bien. Soluciona un problema diferente relacionado con la animación de UITextFields al usar UIControlEventEditingDidEnd. Cambié a esta configuración y las animaciones fueron arregladas. – jasonjwwilliams

+0

Esto ya no funciona en iOS 8.1 (al menos). –