Подождите, пока блок анимации не завершится, прежде чем переходить

Я внедряю несколько простых анимаций в приложение для своих карт.

Пока все отлично работает, но мне нужно исправить еще одну деталь, прежде чем я смогу сказать, что все готово.

Сценарий довольно прост:

Три карты должны покинуть экран с анимацией, прежде чем переход модально отобразит новый экран.

До сих пор анимация выполняется и загружается новый вид, но деталь, которую я не смог проработать, - это «подождите, пока анимация завершится, прежде чем отображать новый вид».

Я делаю это так:

1) Установите анимацию выхода с помощью этого метода

- (void)performExitAnimationWithCompletionBlock:(void (^)(BOOL))block
{    
    [UIView animateWithDuration:0.1f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^
     {
         self.optionOneFront.center = self.optionOneBack.center = self.optionTwoFront.center;
         self.optionOneFront.transform = self.optionOneBack.transform = self.optionTwoFront.transform;

         self.optionThreeFront.center = self.optionThreeBack.center = self.optionTwoFront.center;
         self.optionThreeFront.transform = self.optionThreeBack.transform = self.optionTwoFront.transform;
     }
                     completion:^(BOOL finished)
     {
         CGPoint point = CGPointMake(self.optionTwoFront.center.x, self.view.frame.size.height * -2.0f);

         [UIView animateWithDuration:1.0f
                               delay:0.0f
                             options:UIViewAnimationOptionCurveEaseOut
                          animations:^
          {
              self.optionOneFront.center   = point;
              self.optionOneBack.center    = point;
              self.optionTwoFront.center   = point;
              self.optionTwoBack.center    = point;
              self.optionThreeFront.center = point;
              self.optionThreeBack.center  = point;
          }
                          completion:block];
     }];
}

2) Попробуйте обернуть код перехода в анимацию перед представлением VC «AddOptions».

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [self performExitAnimationWithCompletionBlock:^(BOOL finished)
     {
         // Executes the following "if" statement if the user wants to add new options
         if ([segue.identifier isEqualToString:@"AddOptions"])
         {
             UINavigationController *navigationController = segue.destinationViewController;
             OptionsViewController *controller = (OptionsViewController *)navigationController.topViewController;
             controller.delegate = self;
         }         
     }];    
}

Как я уже говорил, все работает, но модальные окна появляются до окончания анимации.

Есть идеи, что мне не хватает?


person Juan González    schedule 01.08.2012    source источник


Ответы (1)


Вместо того, чтобы запускать анимацию в методе prepareForSeque, вам следует попробовать вызвать [self performExitAnimationWithCompletionBlock], когда вы хотите запустить процесс анимации, а затем вручную запустить последовательность, используя метод [self performSegueWithIdentifier] в блоке завершения финальной анимации.

Я предполагаю, что ваша последовательность в настоящее время связана с нажатием кнопки в вашей раскадровке. Если это так, вам придется отключить его в раскадровке. Возможно, вы сможете сохранить последовательность, подключившись к невидимой кнопке на раскадровке, чтобы она никогда не запускалась автоматически.

Вместо этого напишите код кнопки следующим образом:

-(void)btnStartSeque:(id)sender{

      //trigger animations

      [self performExitAnimationWithCompletionBlock:^(BOOL finished){
         [self performSegueWithIdentifer:@"AddOptions" sender:self];
     }];    
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

   // Executes the following "if" statement if the user wants to add new options
    if ([segue.identifier isEqualToString:@"AddOptions"])
    {
      UINavigationController *navigationController = segue.destinationViewController;
      OptionsViewController *controller = (OptionsViewController *)navigationController.topViewController;
      controller.delegate = self;
    }               
}

Альтернативное (и, возможно, лучшее?) решение для получения желаемой функциональности состоит в том, чтобы вообще не использовать последовательность, а вместо этого вручную перемещать экран. В этом случае полностью удалите последовательность из раскадровки. Также убедитесь, что вы указали идентификатор для OptionsViewController в раскадровке. Выполните следующий код для действия, вызывающего анимацию/переход:

-(void)btnStartModalTransition:(id)sender{

      //trigger animations

      [self performExitAnimationWithCompletionBlock:^(BOOL finished){

          //load the storyboard (sub in the name of your storyboard)
          UIStoryBoard* storyBoard = [UIStoryBoard storyBoardWithName:@"MyStoryBoard" bundle:nil]
          //load optionsviewcontroller from storyboard
          OptionsViewController *controller = (OptionsViewController *)[storyBoard instantiateViewControllerWithIdentifier:@"OptionsViewControllerIdentifier"];
          UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];

         controller.delegate = self;
         [self presentModalViewController:navigationController animated:YES];
     }];    
}
person pdriegen    schedule 01.08.2012
comment
Привет pdriegen, спасибо за ответ. Ваше предложение улучшает реализацию, но основная проблема остается. PerformExitAnimationWithCompletionBlock не завершается, когда приходит переход. Кроме того, я предполагаю, что, поскольку я вызываю AddOptions в методе кнопки, я могу удалить его из prepareForSegue, верно? Я думаю, что if ([segue.identifier isEqualToString:@AddOptions]) больше не нужен. - person Juan González; 02.08.2012
comment
@JuanGonzález: да, я не заметил, что последовательность должна быть настроена в раскадровке, чтобы она не срабатывала автоматически. Я также предоставил альтернативное решение, которое вообще не использует последовательности, которое может работать лучше. Обратите внимание, что я на самом деле ничего из этого не тестировал... - person pdriegen; 02.08.2012
comment
Ничего страшного. Ваш ответ дал мне ориентацию, необходимую для ее решения. Спасибо! - person Juan González; 02.08.2012
comment
К вашему сведению, вы все еще можете использовать переход, не нужно ставить его на невидимую кнопку или что-то еще. Просто сделайте так, чтобы переход переходил от экрана к экрану (а не к какому-либо отдельному элементу). - person pfrank; 28.09.2013