Wait until animation block finishes before segue

放肆的年华 提交于 2019-12-10 10:13:00

问题


I'm implementing some simple animations to my cards app.

Everything is working great so far but I have just one more detail to fix before I can say it is done.

The scenario is pretty simple:

Three cards must exit the screen with an animation before segue modally brings up the new screen.

Up until now he animation gets executed and the new view is loaded, but the detail I haven't been able to work out is the "wait until the animation finishes before bringing the new view".

This is how I'm doing it:

1) Set exit animation with this method

- (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) Try to wrap the segue code within the animation before presenting the "AddOptions" VC

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

As I said before, everything works but the modal windows comes up before the animation finishes.

Any idea of what I'm missing?


回答1:


Instead of triggering the animation in the prepareForSeque method, you should try calling [self performExitAnimationWithCompletionBlock] when you want to start the animation process, and then trigger the seque manually using the [self performSegueWithIdentifier] method in the completion block of the final animation.

I'll assume that your seque it currently connected to a button touch in your storyboard. If that's the case you'll have to disconnect it in the storyboard. Perhaps you can keep the seque alive by connecting to an invisible button on your storyboard so that it can never be automatically fired.

Instead, write the button code like so:

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

An alternative (and perhaps better?) solution to get the functionality you want is not to use a seque at all, but instead manually transition the screen. In this case, delete the seque entirely from the storyboard. Also ensure you provide an identifier for OptionsViewController in the storyboard. Execute the following code on the action that causes the animation/transition:

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


来源:https://stackoverflow.com/questions/11756572/wait-until-animation-block-finishes-before-segue

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