我想做三个交错的视图动画。为此,我将GCD和视图动画混合如下:

编辑-我想用viewA,然后viewB,然后viewC的子级进行翻转动画。我希望这些动画重叠...

random external action causes:  A-----------A'
                                    B-----------B'
                                        C---------C'


问题是,当在A-> C'动画期间发生触发动作时,这三个状态会混合在一起。我想要一种将三个交错动作作为一个不间断的动作来进行的方法。

- (void)flipAnimated:(BOOL)animated {
    // views A,B,C are initialized here
    // kFLIPDURATION is 0.8
    NSTimeInterval interval = (animated)? kFLIPDURATION / 2.0 : 0;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self flipChildrenOfView:viewA animated:animated];
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self flipChildrenOfView:viewB animated:animated];
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2*interval * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self flipChildrenOfView:viewC animated:animated];
    });
}

- (void)flipChildrenOfView:(UIView *)parent animated:(BOOL)animated {
    // some setup here to get visible and hidden views
    [UIView transitionFromView:visibleView
                        toView:hiddenView
                      duration:((animated)? kFLIPDURATION : 0)
                       options:UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionShowHideTransitionViews
                    completion:nil];
}


这很好用,除了有计时器事件,有时还有用户动作驱动这些事件,而且在动画进行过程中,经常每一次都调用flipAnimated:。结果是混淆了观点和悲伤。

到目前为止,我尝试的是(1)阅读,他们对GCD替代方案感到困惑。 (2)我尝试了一个名为animating的实例变量,在我的视图动画调用方法中添加了一个完成块,然后执行了此操作...

@property(assign,nonatomic) BOOL animating;

- (void)flipAnimated:(BOOL)animated {
    if (self.animating) return;
    self.animating = YES;
    NSTimeInterval interval = (animated)? kFLIPDURATION / 2.0 : 0;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self flipChildrenOfView:viewA animated:animated completion:nil];
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self flipChildrenOfView:viewB animated:animated completion:nil];
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2*interval * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self flipChildrenOfView:viewC animated:animated completion:^(BOOL finished) {
            self.animating = NO;
        }];
    });
}


但是a,同样的行为。我可以观察到该块似乎可以与NSLogs一起使用,但是视图仍然会混淆。 (先进行第二次翻转,然后再进行之前的翻转)。我认为这是因为我在并发方面费了心思。

一定会有所帮助,特别是代码示例。 ---几乎忘了:比停止并发请求更好的是,让它排队,然后在运行结束后运行。

最佳答案

transitionFromView:...的文档确实说:“除非正在运行另一个动画,否则视图转换将立即开始,在这种情况下,它会在当前动画完成后立即开始。”因此重叠的动画将无法像这样工作。

放到CoreAnimation,例如CATransform3D,请参见Core animation animating the layer to flip horizontally

10-06 13:25
查看更多