Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIView在动画内部正确地从SuperView移除_Ios_Cocoa Touch - Fatal编程技术网

Ios UIView在动画内部正确地从SuperView移除

Ios UIView在动画内部正确地从SuperView移除,ios,cocoa-touch,Ios,Cocoa Touch,现在,这个问题已经问了很多,但没有一个真正考虑到消息如何(或何时)消失。几乎每个示例都使用以下设计: [UIView animateWithDuration:0.5 delay:1.0 options: UIViewAnimationCurveEaseOut animations:^{ yourView.alpha = 0; }completion:^(BOOL finished){ [yourView removeFromSupe

现在,这个问题已经问了很多,但没有一个真正考虑到消息如何(或何时)消失。几乎每个示例都使用以下设计:

[UIView animateWithDuration:0.5
    delay:1.0
    options: UIViewAnimationCurveEaseOut
    animations:^{
        yourView.alpha = 0;
    }completion:^(BOOL finished){
        [yourView removeFromSuperview]; // Called on complete
    }];
问题是,这些消息都将在反动画结束时发送! 现在,
-addSubview
可以设置动画(如果放在动画块中),它将发送具有正确时差的相应消息(
-viewwillbeen
&
-viewdidebeen
)。因此,人们自然会将
-removeFromSuperview
放在动画块中。这将正确发送消息,但视图实际上会立即删除,使动画。。。嗯,它不会动画,因为没有任何东西可以动画

这是苹果故意的吗?如果是,为什么?你如何正确地做这件事

谢谢

编辑。

只是为了弄清楚我在做什么: 我得到了一个自定义的segue,从顶部垂直设置了一个子ViewController的动画,其工作原理与预期一致,代码如下:

    -(void)perform{
        UIViewController *srcVC = (UIViewController *) self.sourceViewController;
        UIViewController *destVC = (UIViewController *) self.destinationViewController;

        destVC.view.transform = CGAffineTransformMakeTranslation(0.0f, -destVC.view.frame.size.height);
        [srcVC addChildViewController:destVC];
        [UIView animateWithDuration:0.5f
                         animations:^{
                             destVC.view.transform = CGAffineTransformMakeTranslation(0.0f, 0.0f);
                             [srcVC.view addSubview:destVC.view];
                         }
                         completion:^(BOOL finished){
                             [destVC didMoveToParentViewController:srcVC];
                         }];
    }
在这里,它将按以下顺序发生(由于
-addSubview
位于动画块内):

  • 添加子视图(将自动调用
    -willMoveToParentViewController
  • -addSubview
    将调用
    -view将出现
  • 当动画完成时,
    -addSubview
    将调用
    -viewdide
  • 在完成块内手动调用
    -didMoveToParentViewController
  • 以上是确切的预期行为(就像内置的转换行为一样)

    使用以下代码执行上述步骤但向后(使用unwindSegue):

    流程如下所示:

    [self addChildViewController:self.childViewController];    
    [self.view addSubview:self.childViewController.view];
    [self.childViewController didMoveToParentViewController:self];
    
  • 手动调用
    -willMoveToParentView:nil
    以通知它将被删除
  • 当动画完成时,将同时调用
    -viewwillEnglish
    &
    -viewDidEnglish
    -removeFromParentViewController
    将自动调用
    -didMoveToParentViewController:nil

  • 如果我现在将
    -removeFromSuperview
    移动到动画块中,事件将正确发送,但视图将在动画开始时而不是动画结束时被删除(这是没有意义的部分,遵循
    -addSubview
    的行为)。

    您的问题是关于删除视图控制器,因为,
    视图将消失
    视图消失
    是视图控制器的方法

    视图将消失:
    将从完成块调用,而不是更早,因为这是您说过要从主视图中删除子视图的位置

    如果要删除该点之前的某些属性,则在子控制器中重写
    willMoveToParentViewController:
    方法。此方法将在动画块之前调用。 下面是代码示例:

    //Prepare view for removeing.
    [self.childViewController willMoveToParentViewController:nil];
    [UIView animateWithDuration:0.5
                          delay:1.0
                        options: UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         self.childViewController.view.alpha = 0;
                     }completion:^(BOOL finished){
                         [self.childViewController.view removeFromSuperview];
                         [self.childViewController didMoveToParentViewController:self];
                     }];
    
    因此,流程将是:

  • 第一个
    将调用带有nil参数的movetoparentviewcontroller:
  • 动画块将启动,视图将其alpha属性设置为0
  • 动画完成后,完成块将开始执行
  • [self.childViewController.view removeFromSuperview]将首先被调用
  • 然后将调用childViewController中的
    viewwilldisapear:
  • 然后
    [self.childViewController didMoveToParentViewController:self]
  • 最后,将执行childViewController中的
    viewDidDissapear:
  • 此流的预请求是使用如下代码嵌入childViewController:

    [self addChildViewController:self.childViewController];    
    [self.view addSubview:self.childViewController.view];
    [self.childViewController didMoveToParentViewController:self];
    

    您看到的是您应该期望的,因为您正在即时删除视图。ViewWillEverge和ViewDidEverge被一个接一个地调用有什么问题?在这些方法中,您希望如何处理这一问题?
    yourView
    似乎是一个
    UIView
    对象,
    -ViewWillAsped
    -ViewDidAsped
    -ViewWillEverge
    -ViewDidEverge
    都是
    UIViewController
    的实例方法,不
    ui查看
    's@rdelmar在我的例子中,这是一个UnwindSegue,在´-viewwilldefine´应该同时启动一个“scrollUp”动画来创建一个好的效果。尽管如此,重要的是,当您希望消息以合乎逻辑的方式为其他编码人员工作时发送消息。@staticwoodman是的,您是对的,我应该更清楚地说明这一点。我的观点是,这些消息是通过在UIView上执行的操作发送的,这就是为什么我没有提到VC。我认为您的问题可能是使用了错误的动画方法来完成任务。您可能希望查看UIViewController方法transitionFromViewController:toViewController:duration:options:animations:completion:(或者UIView方法transitionFromView:toView:duration:options:completion:,或者transitionWithView:duration:options:animations:completion:)。如果不知道你具体想做什么,很难给你进一步的建议。谢谢你的回答!是的,这些消息被发送到视图控制器的实例,但由于UIView的状态更改而被调用,这就是我这样解释的原因。我实际上是在执行一个展开阶段,这基本上只是一个垂直向上(向外)滑动。您的解决方案仍然无法解决问题,因为仍然会同时调用消息´-ViewWillEnglish´&´-ViewDidEnglish´(因为正如您所说,它们只与´-removeFromSuperview´)相关)。正如我在´-addSubview´中所解释的,我需要这些事件与动画同步发生。是否尝试从“-viewWillDissapear:”中删除对“-scrollUp”方法的调用?也许你可以发布通知开始