6

「欲しい」iPhoneアプリの背景を模倣したいのですが、ビューを循環させたい3つの色があります。赤、青、緑としましょう。

画面の 1/3 ごとに赤から青、緑へのグラデーションが必要です (グラデーション)。次に、赤が画面の上部から消えて下部に戻ってくるようにします。(下の写真を参照してください...)

アニメーションは上に移動する必要があります。勾配が上に移動し、画面の下部に再形成されて上に移動する必要があります。

私は CAGradientLayer を使用して「色」プロパティをアニメーション化しようとしましたが、すべてが互いにフェードアウトするように見え、必ずしも画面から移動するわけではありません。

OpenGL の使用を検討していますが、非常に単純に見えるものをそれほど低くしたくありません。ヘルプ/コード サンプルは大歓迎です。基本的に、CoreAnimation/CoreGraphics を使用してグラデーションをアニメーション化するのに助けが必要です。

前もって感謝します!

ここに画像の説明を入力

ここに画像の説明を入力

ここに画像の説明を入力

4

2 に答える 2

6

colorsあなたが発見したように、CAGradientLayerのプロパティをアニメーション化すると、単にフェードが発生します。ただし、グラデーションレイヤーが適していると思います。次のオプションを確認する必要があります。

  • positionsの代わりに / と同様にプロパティをアニメーション化しますcolors
  • アニメーション サイクル全体を含む大きなグラデーション レイヤーを作成し、その位置をアニメーション化する

2 番目のオプションでは、勾配を再計算する必要がないため、おそらく最高のパフォーマンスが得られます。

于 2013-06-30T06:42:46.497 に答える
0

GradientView クラスを作成するには、UIView をサブクラス化する必要があります。移動中の色を保持する配列を追加します。選択は重要であり、その理由を説明する記事を書きました。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 に答える