xcode 等到动画块完成后再转场

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11756572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 01:05:50  来源:igfitidea点击:

Wait until animation block finishes before segue

xcodeios5animationsegueblock

提问by Juan González

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.

三张卡片必须以动画形式退出屏幕,然后 segue 以模态方式调出新屏幕。

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

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

2) 尝试在呈现“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?

知道我缺少什么吗?

采纳答案by pdriegen

Instead of triggering the animation in the prepareForSequemethod, 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.

与其在prepareForSeque方法中触发动画,[self performExitAnimationWithCompletionBlock]不如尝试在想要启动动画过程时调用,然后[self performSegueWithIdentifier]在最终动画的完成块中使用方法手动触发seque 。

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:

获得您想要的功能的另一种(也许更好?)解决方案是根本不使用序列,而是手动转换屏幕。在这种情况下,请从故事板中完全删除序列。还要确保在情节提要中为 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];
     }];    
}