【问题标题】:Wait until animation block finishes before segue等到动画块在segue之前完成
【发布时间】:2012-07-30 04:35:25
【问题描述】:

我正在为我的卡片应用程序实现一些简单的动画。

到目前为止,一切都很好,但在我说它完成之前,我还有一个细节需要修复。

场景非常简单:

在 segue 模态显示新屏幕之前,三张卡片必须以动画形式退出屏幕。

到目前为止,他的动画被执行并加载了新视图,但我无法解决的细节是“等到动画完成后再引入新视图”。

我就是这样做的:

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) 在呈现“AddOptions” VC 之前尝试将 segue 代码包装在动画中

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

正如我之前所说,一切正常,但模式窗口会在动画结束之前出现。

知道我错过了什么吗?

【问题讨论】:

    标签: xcode ios5 animation segue block


    【解决方案1】:

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

    我假设您的序列当前连接到故事板中的按钮触摸。如果是这种情况,您将不得不在情节提要中断开它。也许您可以通过连接到情节提要上的一个不可见按钮来保持序列的活力,这样它就永远不会被自动触发。

    改为这样编写按钮代码:

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

    【讨论】:

    • 您好 pdriegen,感谢您的回复。您的建议改进了实施,但主要问题仍然存在。当 segue 进入时 performExitAnimationWithCompletionBlock 没有完成。另外,我猜因为我在按钮方法中调用了“AddOptions”,所以我可以将它从 prepareForSegue 中删除,对吧?我认为不再需要“if ([segue.identifier isEqualToString:@"AddOptions"])”。
    • @JuanGonzález:是的,我没有注意到必须在情节提要中调整续集才能自动触发。我还提供了一个完全不使用可能效果更好的序列的替代解决方案。请注意,我实际上还没有测试过这些......
    • 没关系。您的回答给了我解决问题所需的方向。谢谢!
    • 仅供参考,您仍然可以使用 segue,无需将其放在不可见的按钮或任何东西上。只需让 segue 从一个屏幕转到另一个屏幕(不是任何单个元素)。
    猜你喜欢
    • 2017-03-15
    • 2018-07-14
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    相关资源
    最近更新 更多