6

我想模仿“想要”的 iPhone 应用程序背景,我想让视图循环显示 3 种颜色,比如说红色、蓝色和绿色。

我希望有一个从红色到蓝色到绿色的渐变,每个屏幕的 1/3,相互淡入(渐变),然后,我希望红色在顶部离开屏幕并从底部返回。(见下面的照片......)

动画应该向上移动,我希望渐变在屏幕底部向上并重新向上。

我尝试使用 CAGradientLayer 并为“colors”属性设置动画,但这看起来就像一切都相互淡入,不一定会移出屏幕。

考虑使用 OpenGL,但不想因为看起来很简单的东西而降低。任何帮助/代码示例将不胜感激。我基本上需要帮助使用 CoreAnimation/CoreGraphics 为渐变设置动画。

提前致谢!

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

4

2 回答 2

6

正如您所发现的,为 CAGradientLayer的colors属性设置动画只会导致淡入淡出。但是我认为渐变层是要走的路。您应该查看以下选项:

  • 动画positions属性以及 / 而不是colors.
  • 创建一个更大的渐变层,其中包含您的完整动画周期并为其位置设置动画

第二个选项可能会提供最佳性能,因为不需要重新计算梯度。

于 2013-06-30T06:42:46.497 回答
0

您应该继承 UIView 以创建 GradientView 类。添加一个数组来保存您正在移动的颜色。选择很重要,我写了一篇文章解释了原因。覆盖drawRect(rect: CGRect)方法并在颜色的组件之间进行插值:

override func drawRect(rect: CGRect) {

   let context = UIGraphicsGetCurrentContext();
   CGContextSaveGState(context);

   let c1 = colors[index == 0 ? (colors.count - 1) : index - 1] // previous
   let c2 = colors[index]                                       // current
   let c3 = colors[index == (colors.count - 1) ? 0 : index + 1] // next

   var c1Comp = CGColorGetComponents(c1.CGColor)
   var c2Comp = CGColorGetComponents(c2.CGColor)
   var c3Comp = CGColorGetComponents(c3.CGColor)

   var colorComponents = [
       c1Comp[0] * (1 - factor) + c2Comp[0] * factor, // color 1 and 2
       c1Comp[1] * (1 - factor) + c2Comp[1] * factor,
       c1Comp[2] * (1 - factor) + c2Comp[2] * factor,
       c1Comp[3] * (1 - factor) + c2Comp[3] * factor,
       c2Comp[0] * (1 - factor) + c3Comp[0] * factor, // color 2 and 3
       c2Comp[1] * (1 - factor) + c3Comp[1] * factor,
       c2Comp[2] * (1 - factor) + c3Comp[2] * factor,
       c2Comp[3] * (1 - factor) + c3Comp[3] * factor    
   ]

   let gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), &colorComponents, [0.0, 1.0], 2)

   let startPoint = CGPoint(x: 0.0, y: 0.0)
   let endPoint = CGPoint(x: rect.size.width, y: rect.size.height)
   CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsAfterEndLocation)

   CGContextRestoreGState(context);
}

index 变量从 0 开始并环绕颜色数组,而因子在 0.0 和 1.0 之间并通过计时器进行动画处理:

var index: Int = 0
var factor: CGFloat = 1.0
var timer: NSTimer?

func animateToNextGradient() {
    index = (index + 1) % colors.count
    self.setNeedsDisplay()
    self.factor = 0.0    
    self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0/60.0, target: self, selector: "animate:", userInfo: nil, repeats: true)

}

func animate(timer: NSTimer) {
    self.factor += 0.02
    if(self.factor > 1.0) {
        self.timer?.invalidate()
    }
    self.setNeedsDisplay()
}
于 2014-03-18T15:47:47.173 回答