2016-04-10 18 views
3

形状が正しく入力されていますが、塗りつぶしの色を変更する方法や、塗りつぶしの色の変更をアニメーション化する方法を把握することができません。UIBezierPath。ちょうどUIViewの背景色を変更するのが私が探しているものです。UIBezierPathで塗りつぶしの色の変更をアニメーション化する方法は?

var fillColor = UIColor() 

func changeBackgroundColor() { 

    let animcolor = CABasicAnimation(keyPath: "fillColor") 
    animcolor.fromValue = UIColor.greenColor() 
    animcolor.toValue = UIColor.orangeColor() 
    animcolor.duration = 1.0; 
    animcolor.repeatCount = 0; 
    animcolor.autoreverses = true 
    shapeLayer.addAnimation(animcolor, forKey: "fillColor") 

} 


var fillColor = UIColor() 
let clipPath = UIBezierPath() 
let shapeLayer = CAShapeLayer() 

override func drawRect(rect: CGRect) { 

     clipPath.moveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY - 0.25)) 
     clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 9.79), controlPoint2: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 26.06)) 
     clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX + 17.69, self.bounds.minY + 46.13), controlPoint2: CGPointMake(self.bounds.minX + 33.96, self.bounds.minY + 46.13)) 
     clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1)) 
     clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 44.01, self.bounds.minY + 0.19)) 
     clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 7.58, self.bounds.minY + 0.19)) 
     clipPath.usesEvenOddFillRule = true 
     fillColor = userColor 
    } 

clipPath.addClip() 
fillColor.setFill() 
clipPath.fill() 
shapeLayer.path = clipPath.CGPath 
self.layer.mask = shapeLayer 

答えて

0

だけのUIViewの背景色を変更するような私が探しているものです。

なぜあなたはそれを正確に行うことはできませんか?あなたはすでにあなたのパスへのビューをマスクしています - あなたの背景色をアニメーション化することで、あなたが望む正確な効果を得ることができます。 Core Graphicsパスの塗りつぶしを取り除き、のように、drawRectのオーバーライドを削除してください。

あなた本当にdrawRectを使用して色をアニメーション化する必要がある場合は、UIViews二つにあなたのUIViewを分割検討することもでき - 1(アニメート可能性)背景レイヤーを描画すると、カスタム描画を描画する1。または、CADisplayLinkを設定して、中間の背景色を持つすべてのフレームを再描画することもできますが、パフォーマンスはそれほど優れていません。

私が以下で言うように、UIBezierPathの塗りつぶし色を直接アニメーション化することはできません。塗りつぶしの色を既存のコードで変更するだけの場合は、userColorsetNeedsDisplayを呼び出すだけです。

マスキングと塗りつぶしに2つの異なるパスを使用しているため、これを求めている場合は、下の(後ろ向きでは複雑すぎる)回答を参照してください。


問題は、UIBezierPathの塗りつぶしの色はアニメーション化できません。しかし、CAShapeLayerの塗りつぶしの色はです。

したがって、代わりに別のCAShapeLayerを使用したいとします。機能を明確にするために、fillLayermaskLayerプロパティを作成することをおすすめします。これで、100%レイヤー化されたアプローチが使用されているため、コアグラフィックスの描画をやめているため、コードをdrawRectから移動することができます。

また、値とのアニメーションにはCGColorを使用する必要があります。このような

何かがトリックを行う必要があります。

var fillColor = UIColor.greenColor() 
let maskLayer = CAShapeLayer() 
let fillLayer = CAShapeLayer() 

func changeBackgroundColor() { 

    let animcolor = CABasicAnimation(keyPath: "fillColor") 
    animcolor.fromValue = UIColor.greenColor().CGColor 
    animcolor.toValue = UIColor.orangeColor().CGColor 
    animcolor.duration = 1.0; 
    animcolor.repeatCount = 0; 
    animcolor.autoreverses = true 
    fillLayer.addAnimation(animcolor, forKey: "fillColor") 

} 

// re-adjust the clipping path when the view bounds changes 
override func layoutSubviews() { 

    let clipPath = UIBezierPath() 
    clipPath.moveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY - 0.25)) 
    clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 9.79), controlPoint2: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 26.06)) 
    clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX + 17.69, self.bounds.minY + 46.13), controlPoint2: CGPointMake(self.bounds.minX + 33.96, self.bounds.minY + 46.13)) 
    clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1)) 
    clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 44.01, self.bounds.minY + 0.19)) 
    clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 7.58, self.bounds.minY + 0.19)) 

    // update layer paths 
    fillLayer.path = clipPath.CGPath 
    maskLayer.path = clipPath.CGPath 

} 

override init(frame: CGRect) { 
    super.init(frame: frame) 

    // configure filling 
    fillLayer.fillColor = fillColor.CGColor 
    fillLayer.fillRule = kCAFillRuleEvenOdd 

    // add fill path to superlayer 
    layer.addSublayer(fillLayer) 

    // configure masking layer 
    maskLayer.fillRule = kCAFillRuleEvenOdd 
    layer.mask = maskLayer 
} 
+0

でコードを確認することができます。より良い実装に取り​​組んでいただきありがとうございます。しかし、 'fillLayer'の塗りつぶしの色をアニメーション化することはできません。私はそれを変更することさえできません。この関数は間違いなく呼び出されています。これは私が座って、30-40分でそれを突き抜けて終わると思うようなものです。 –

+0

@spacemonkeyアニメーション化する前に 'fillLayer'が画面に表示されていますか? 'frame'がゼロでないことを確認し、レイヤー階層に追加します。上記のコードを使用している場合は、 'init(frame:)'イニシャライザで 'UIView'を初期化する必要があります(実際には、サイズ関連のコードを'例えば、「レイアウトサブビュー」)。 – Hamish

+0

ありがとうございます。正確にどこで、そしてサイズであるべきか。塗りつぶしの色は、同じものでなければならないものに設定されています。他のものに変更されることはありません。 –

0

スウィフト4バージョンを、あなたは素晴らしいです遊び場

var fillColor = UIColor.green 
 
let maskLayer = CAShapeLayer() 
 
let fillLayer = CAShapeLayer() 
 

 
func changeBackgroundColor() { 
 
    
 
    let animcolor = CABasicAnimation(keyPath: "fillColor") 
 
    animcolor.fromValue = UIColor.green.cgColor 
 
    animcolor.toValue = UIColor.orange.cgColor 
 
    animcolor.duration = 1.0; 
 
    animcolor.repeatCount = 0; 
 
    animcolor.autoreverses = true 
 
    fillLayer.add(animcolor, forKey: "fillColor") 
 
    
 
} 
 

 
// re-adjust the clipping path when the view bounds changes 
 

 
let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) 
 
view.backgroundColor = UIColor.white 
 

 
func createPaths() { 
 
    let clipPath = UIBezierPath() 
 
    clipPath.move(to: CGPoint(x: view.bounds.minX + 7.65, y: view.bounds.minY - 0.25)) 
 
    clipPath.addCurve(to: CGPoint(x: view.bounds.minX + 7.65, y: view.bounds.minY + 36.1), 
 
         controlPoint1: CGPoint(x: view.bounds.minX - 2.38, y: view.bounds.minY + 9.79), 
 
         controlPoint2: CGPoint(x: view.bounds.minX - 2.38, y: view.bounds.minY + 26.06)) 
 
    clipPath.addCurve(to: CGPoint(x: view.bounds.minX + 43.99, y: view.bounds.minY + 36.1), 
 
         controlPoint1: CGPoint(x: view.bounds.minX + 17.69, y: view.bounds.minY + 46.13), 
 
         controlPoint2: CGPoint(x: view.bounds.minX + 33.96, y: view.bounds.minY + 46.13)) 
 
    
 
    clipPath.addLine(to: CGPoint(x: view.bounds.minX + 43.99, y: view.bounds.minY + 36.1)) 
 
    clipPath.addLine(to: CGPoint(x: view.bounds.minX + 44.01, y: view.bounds.minY + 0.19)) 
 
    clipPath.addLine(to: CGPoint(x: view.bounds.minX + 7.58, y: view.bounds.minY + 0.19)) 
 
    
 
    // update layer paths 
 
    fillLayer.path = clipPath.cgPath 
 
    maskLayer.path = clipPath.cgPath 
 
    
 
    fillLayer.fillColor = fillColor.cgColor 
 
    fillLayer.fillRule = kCAFillRuleEvenOdd 
 
    view.layer.addSublayer(fillLayer) 
 
    maskLayer.fillRule = kCAFillRuleEvenOdd 
 
    view.layer.mask = maskLayer 
 
} 
 

 
createPaths()

関連する問題