1

我在尝试让自定义 UIView 类淡化它的背景时遇到了麻烦。我已经检查了以下 StackOverflow 问题,但它们似乎对我不起作用。

在 UIView 中将背景颜色从一种颜色淡化为另一种颜色

你如何明确地为 CALayer 的 backgroundColor 设置动画?

所以我有一个自定义的 UIView,用户可以在其中绘制东西。如果他们画的东西不正确,我想让背景颜色变红然后变回白色。

我在自定义 UIView 中有这个自定义方法,称为

- (void)indicateMistake;

当我调用该方法时,我希望它执行背景颜色动画,所以我在方法中有这个:

CABasicAnimation* fade = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
fade.fromValue = (id)[UIColor whiteColor].CGColor;
fade.toValue = (id)[UIColor redColor].CGColor;
[fade setDuration:3];
[self.layer addAnimation:fade forKey:@"fadeAnimation"];

但是当我这样做时似乎什么都没有发生。

所以然后我尝试了一个愚蠢的旋转动画,看看它是否有效:

CABasicAnimation* rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotate.toValue = [NSNumber numberWithInt:M_PI];
[rotate setDuration:1];
[self.layer addAnimation:rotate forKey:@"rotateAnimation"];

出于某种原因,自定义 UIView 会旋转。

然后阅读更多 StackOverflow 答案我尝试了这个:

[UIView animateWithDuration:3 animations:^{
    [self setBackgroundColor: [UIColor redColor]];
} completion:^(BOOL finished) {
    [self setBackgroundColor: [UIColor whiteColor]];
}];

这会将颜色从红色变为白色,然后立即变回白色。有时它是如此之快,我有时看不到它发生。如果我评论[self setBackgroundColor: [UIColor whiteColor]];它保持红色。但是有节点逐渐从白色到红色的效果。

我已经没有想法了..任何帮助将不胜感激!

4

3 回答 3

9
[UIView animateWithDuration:0.3f animations:^{
   fade.layer.backgroundColor = [UIColor redColor].CGColor;
}

这假设您已将淡入淡出视图预设为您想要的白色。

您最后一次尝试动画跳回白色的原因是因为在 animateWithDuration 的完成子句中,您将视图设置回白色。

该完成子句在动画完成时执行,因此动画(白色-红色)发生,然后您的编译器完成并将淡入淡出视图跳回白色。

作为额外的奖励:

我敢肯定,您可能想知道如何才能变回白色。

好吧,让我们假设按下 aUIButton调用这个名为“animateColors”的函数。话虽如此,只需实现一个 BOOL。

- (void)animateColors {        
    if (!isRed) {
        [UIView animateWithDuration:0.3f animations:^{
            fade.layer.backgroundColor = [UIColor redColor].CGColor;
        }];
        isRed = YES;
    } else if (isRed) {
        [UIView animateWithDuration:0.3f animations:^{
            fade.layer.backgroundColor = [UIColor whiteColor].CGColor;
        }];
        isRed = NO;
    }
}

显然,您将要在接口或头文件中对布尔值 isRed 进行属性声明。

于 2013-01-27T00:51:55.270 回答
5

所以我有一个自定义的 UIView,用户可以在其中绘制东西。

我假设这意味着你已经实现了-drawRect:.

IIRC, by default (if UIView.clearsContextBeforeDrawing is set), the context gets filled with the view's background colour, -drawRect: gets called, and the resulting bitmap is drawn on screen instead of the background colour. Animating this would mean animating between the two bitmaps, which isn't something Core Animation is particularly good at. (I could be wrong about the details here, but it explains the behaviour).

The easiest fix is to set the background colour to [UIColor clearColor] and animate the background colour of a view behind the one you are drawing to. This means the view will not need to be redrawn, only recomposited over the "background".

于 2013-01-27T01:25:04.137 回答
2

我按原样尝试了您的代码。它工作得很好——它从我原来的视图中逐渐褪色到红色,慢慢地(然后又跳回白色,这是你所期望的)。因此,如果这对您不起作用,则会发生其他事情。

一个非常有用的诊断工具是提取您的麻烦代码并制作一个没有其他内容的项目。我做的就是你应该做的。创建一个全新的 Single View Application 项目。现在你有了一个视图控制器和它的视图。实现这个方法:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    CABasicAnimation* fade = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    fade.fromValue = (id)[UIColor whiteColor].CGColor;
    fade.toValue = (id)[UIColor redColor].CGColor;
    [fade setDuration:3];
    [self.view.layer addAnimation:fade forKey:@"fadeAnimation"];
}

运行项目。褪色效果很好。所以你看,任何问题都不在这段代码中!它在别的地方。也许您还有其他代码也在处理颜色 - 一个不同的动画正在破坏这个。也许某些参考不是指您认为的那样。也许有东西覆盖了该层,所以您看不到它(子层)。谁知道?你没有展示你的整个项目(你也不应该)。重要的是向自己证明代码应该可以工作,这样您就可以找出真正的问题所在。我已经向你展示了如何做到这一点。

于 2013-01-27T01:21:28.760 回答