首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >执行多个顺序UIView动画的最佳方式?

执行多个顺序UIView动画的最佳方式?
EN

Stack Overflow用户
提问于 2010-10-03 18:52:08
回答 4查看 11.8K关注 0票数 15

我有一系列的8个UIView动画,这些动画在我的视图加载后立即发生。现在,我正在使用animationDidStop:finished:context委托方法来完成这项工作,一切都按预期进行。问题是我对每个动画都有一个新的方法。这些方法中的大多数代码都是重复的,只有动画持续时间和元素的实际位置发生了变化。

我试图创建一个方法,该方法将被调用,并让上下文保存适当更改UI所需的参数,但它似乎递归地调用自身,远远超过了我调用它的次数:

-(void)animationDidStop:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
    NSNumber *number = (NSNumber *)context;
    int animationStep = [number intValue];
    int nextAnimationStep = animationStep + 1;
    NSNumber *nextAnimationStepNumber = [NSNumber numberWithInt:nextAnimationStep];
    NSLog(@"Animation Step: %i", animationStep);

    CGRect firstFrame = CGRectMake(self.feedsScroll.frame.size.width * 2, 0.0f, self.secondFeedView.view.frame.size.width, self.secondFeedView.view.frame.size.height);
    CGRect thirdFrame = CGRectMake(self.feedsScroll.frame.size.width * 2, 0.0f, self.thirdFeedView.view.frame.size.width, self.thirdFeedView.view.frame.size.height);

    [UIView beginAnimations:nil context:nextAnimationStepNumber];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDelegate:self];

    if (animationStep < 8) 
        [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    NSLog(@"Beginning animations");

    switch (animationStep) {
        case 0:
            [UIView setAnimationDuration:.3];
            self.firstFeedView.view.center = CGPointMake(self.firstFeedView.view.center.x + 30, self.firstFeedView.view.center.y);
            break;
        case 1:
            [UIView setAnimationDuration:.3];
            self.firstFeedView.view.center = CGPointMake(self.firstFeedView.view.center.x  - 30, self.firstFeedView.view.center.y);
            break;
        case 2:
            [UIView setAnimationDuration:.3];
            [self.secondFeedView.view setFrame:firstFrame];
            break;
        case 3:
            [UIView setAnimationDuration:.3];
            self.secondFeedView.view.center = CGPointMake(self.secondFeedView.view.center.x + 30, self.firstFeedView.view.center.y);
            break;
        case 4:
            [UIView setAnimationDuration:.3];
            self.secondFeedView.view.center = CGPointMake(self.secondFeedView.view.center.x - 30, self.firstFeedView.view.center.y);
            break;
        case 5:
            NSLog(@"Animation step 6");
            [UIView setAnimationDuration:.5];
            self.firstFeedView.view.center = CGPointMake(self.firstFeedView.view.center.x - 230, self.firstFeedView.view.center.y);
            self.secondFeedView.view.center = CGPointMake(self.secondFeedView.view.center.x - 230, self.firstFeedView.view.center.y);
            break;
        case 6:
            [UIView setAnimationDuration:.5];
            [self.thirdFeedView.view setFrame:thirdFrame];
            break;
        case 7:
            [UIView setAnimationDuration:.3];
            self.thirdFeedView.view.center = CGPointMake(self.thirdFeedView.view.center.x + 30, self.firstFeedView.view.center.y);
            break;
        case 8:
            [UIView setAnimationDuration:.3];
            self.thirdFeedView.view.center = CGPointMake(self.thirdFeedView.view.center.x - 30, self.thirdFeedView.view.center.y);
            break;
        default:
            break;
    }

    [UIView commitAnimations];  
}

我知道这可能是一个幼稚的实现。我是iPhone开发的新手,正在寻找一些最佳实践应用于此。我是不是走错了路?

EN

回答 4

Stack Overflow用户

发布于 2010-10-04 05:28:57

如果您愿意升级到iOS 4.0,新的基于块的动画方法可以使这种动画链接变得微不足道。例如:

[UIView animateWithDuration:1.0 animations:^{ view.position = CGPointMake(0.0f, 0.0f); } completion:^(BOOL finished){
    [UIView animateWithDuration:0.2 animations:^{ view.alpha = 0.0; } completion:^(BOOL finished){
        [view removeFromSuperview]; }];
}]

将导致view在1秒的持续时间内动画为(0,0),淡出0.2秒,然后从其超级视图中删除。这些动画将是连续的。

+animateWithDuration:animations:completion:类方法中的第一个块包含要立即设置动画的属性更改,第二个块是动画完成时要执行的操作。由于此回调可以包含另一个此类动画,因此您可以嵌套它们来创建任意的动画链。

票数 19
EN

Stack Overflow用户

发布于 2013-04-03 14:38:15

您可以使用块来实现此目的,并获得一个非常干净的结果。

NSMutableArray* animationBlocks = [NSMutableArray new];

typedef void(^animationBlock)(BOOL);

// getNextAnimation
// removes the first block in the queue and returns it
animationBlock (^getNextAnimation)() = ^{
    animationBlock block = (animationBlock)[animationBlocks firstObject];
    if (block){
        [animationBlocks removeObjectAtIndex:0];
        return block;
    }else{
         return ^(BOOL finished){};
    }
};

//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
    [UIView animateWithDuration:1.0 animations:^{
        //...animation code...
    } completion: getNextAnimation()];
}];

//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
    [UIView animateWithDuration:1.0 animations:^{
        //...animation code...
    } completion: getNextAnimation()];
}];

//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
    NSLog(@"Multi-step Animation Complete!");
}];

// execute the first block in the queue
getNextAnimation()(YES);

摘自:http://xibxor.com/objective-c/uiview-animation-without-nested-hell/

票数 16
EN

Stack Overflow用户

发布于 2011-07-28 14:56:02

我们创建了一个组件,用于使用块(CPAnimationSequence on Github)以声明方式链接动画步骤。我们描述了in our iOS development blog的动机和基本原理。

它提供了可读性非常好的代码,如下所示:

[[CPAnimationSequence sequenceWithSteps:
    [CPAnimationStep           for:0.25 animate:^{ self.imageView.alpha = 0.0; }],
    [CPAnimationStep           for:0.25 animate:^{ self.headline.alpha = 0.0;  }],
    [CPAnimationStep           for:0.25 animate:^{ self.content.alpha = 0.0;   }],
    [CPAnimationStep after:1.0 for:0.25 animate:^{ self.headline.alpha = 1.0;  }],
    [CPAnimationStep           for:0.25 animate:^{ self.content.alpha = 1.0;   }],
    nil]
runAnimated:YES];
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3849460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档