Странное поведение при анимации UITextField - PullRequest
5 голосов
/ 11 ноября 2011

Я пытаюсь оживить UITextField, но меня поймала раздражающая и странная проблема.Моя анимация имеет следующую последовательность:

first state

В первом состоянии приложение имеет UITextField, камеру UIButton и отмену UIButton после кнопки камеры, котораяне было показано, потому что он был расположен за пределами приложения.На самом деле мое приложение имеет ширину 320 и начало координат кнопки отмены (350,7)

second state

Во втором состоянии, когда пользователь касается UITextField, альфа-канал кнопки камерыустановлен на 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 в положение, в которое он не должен был уйти.

Проблема в том, что шаг 4 не должен выполняться, а проблема в том, что это происходит только один раз.Если запустить процесс заново (коснитесь поля uitext, введите текст, коснитесь клавиши возврата), шаг 4. не произойдет.

Я потратил целый день, пытаясь решить эту проблему, но мне не удалось.

Ответы [ 3 ]

6 голосов
/ 04 февраля 2012

Спасибо за ответы всех, но я нашел решение некоторое время назад.Правильный способ запуска анимации в UITextField, в зависимости от состояния клавиатуры, - это переопределение методов textFieldShouldBeginEditing и textFieldShouldEndEditing.

Моя первая попытка переопределить textFieldDidBeginEditing и textFieldDidEndEditing для создания анимации.Я не знаю причину, по которой анимации работают в textFieldShouldBeginEditing и textFieldShouldEndEditing, но не в textFieldDidBeginEditing и textFieldDidEndEditing.Но это просто работает.

Моя исправленная версия кода:

- (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 голосов
/ 24 декабря 2011

{отредактировано для улучшения исправления} У меня точно такая же проблема, и некоторые дополнительные детали, а также небольшой взлом, который действительно исправляет ее для меня.

Итак, сначала подробности:

  1. Проблема возникает только при первом увеличении анимации кадра на UITextField и вводе текста в поле.Если UITextField редактируется снова, и те же анимации повторяются, проблема не возникает.
  2. searchField.clearsOnBeginEditing = YES; не устраняет проблему.
  3. Я использовал заполнитель текставсе время проблема наблюдалась.Это не влияет на результаты.
  4. Изменение свойства текста для 1 кадра действительно помогает устранить проблему.

Вот что я делаю, чтобы исправить это:

В моем 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);
    }];
}

Это полностью исправило ситуацию для меня.

0 голосов
/ 23 декабря 2011

Установите некоторый текст заполнителя в поле поиска, _searchField.text = @ "placeholder"

, а также установите _searchField.clearsOnBeginEditing = YES;

Или вы можете просто очистить значение, еслион равен вашему заполнителю в textDidBeginEditing

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...