同时为多个UIView添加动画效果

4

我有三个UIButton对象,它们在视觉上相互堆叠。当用户点击一个按钮时,下面的按钮应该向下移动一定距离。我正在使用以下动画块:

// Assuming button 1 was clicked...
[UIView animateWithDuration:0.25f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^(void) {
                   self.button2.frame = CGRectOffset(self.button2.frame, 0.0f, 20.0f);
                   self.button3.frame = CGRectOffset(self.button3.frame, 0.0f, 20.0f);
                 }
                 completion:^(BOOL finished) { NSLog(@"Finished"); }];

如果我增加动画持续时间,例如从0.25增加到0.75,那么按钮不会保持在一起,而是开始以不同的时间间隔移动。我尝试过使用核心动画方法、组合动画等等,但还没有找到解决方案。您有任何想法吗?现在我将持续时间保持在0.25,直到我想出更好的解决方案。

只是提醒一下,在0.25的时候,它们很可能也以不同的速率移动,只是因为速度而不易察觉。将动画链接起来的最具体的解决方案是使用@bobnoble的解决方案。UIView动画默认只对原始图像进行动画处理,因此这将确保它们保持在一起。 - Ryan Poolos
@RyanPoolos 当然,你是对的。在找到更好的解决方案之前,不注意到这种影响就足够了 :) - elitalon
1个回答

7
一种解决方案是将button2和button3都设置为另一个UIView的子视图,并对该视图进行动画处理,而不是分别对每个按钮进行动画处理。这种方法是否可行取决于您使用堆叠按钮要实现什么目标。
编辑:
由于我的经验是块内的动画同步进行的,因此我实现了如下所示的代码。我尝试了许多动画持续时间的值(0.15、0.25、0.75、1.25),button2和button3是同步移动的(由于button2在button3上面,我实际上看不到button3,直到我点击button2,这会导致button3从button2下面移动)。
- (IBAction)button1Tapped:(id)sender {
    NSLog(@"button1Tapped...");

    [UIView animateWithDuration:0.75f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^(void) {
                         self.button2.frame = CGRectOffset(self.button2.frame, 0.0f, 20.0f);
                         self.button3.frame = CGRectOffset(self.button3.frame, 0.0f, 20.0f);
                     }
                     completion:^(BOOL finished) { NSLog(@"Finished"); }];
}

- (IBAction)button2Tapped:(id)sender {
    NSLog(@"button2Tapped...");

    [UIView animateWithDuration:0.75f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^(void) {
                         self.button3.frame = CGRectOffset(self.button3.frame, 0.0f, 20.0f);
                     }
                     completion:^(BOOL finished) { NSLog(@"Finished"); }];
}

- (IBAction)button3Tapped:(id)sender {
    NSLog(@"button3Tapped...");
}

我曾经考虑过这个问题,但如果明天按钮的数量增加了,这种解决方案就不是“可扩展”的。 - elitalon
@elitalon 为什么不呢?你的按钮已经是视图的子视图了,只需要将它们分组到另一个视图中即可。我不明白为什么你会在缩放方面遇到麻烦。实际上,这似乎更具可扩展性,因为你的动画代码只需要对一个视图进行动画处理。除非我误解了你的要求... - nebs
请注意,如果我有5个按钮,我必须将2、3、4和5分组到一个子视图中。但是,如果我点击按钮2,我必须将3、4和5分组到另一个子视图中。这有点像递归分组... - elitalon
@elitalon - 你使用的 UIButton 是否有什么“特别”的地方?它们是带有图像等自定义按钮,还是其他类型的按钮? - bobnoble
@bobnoble 没错,他们添加了一个UIImageView作为子视图,并且使用自定义图标。 - elitalon
@bobnoble 感谢您的努力!看起来解决方案涉及使用选项 UIViewAnimationOptionCurveEaseOut。更具体地说,不要使用我尝试过的第一个选项 UIViewAnimationOptionCurveLinear。现在我看到所有按钮都按照预期移动了。 - elitalon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接