I am using drawRect to draw a pretty simple shape (dark blue in the image below).
I'd like this to animate from the left to the right, so that it grows. The caveat here is I need there to be a "max" background in gray, as seen in the top part of the image.
Right now, I'm simulating this animation by overlaying a white view, and then animating the size of it, so that it looks like the blue is animating to the right. While this works... I need the background gray shape to always be there. With my overlayed white view, this just doesn't work.
Here's the code for drawing the "current code" version:
let context = UIGraphicsGetCurrentContext()
CGContextMoveToPoint(context, 0, self.bounds.height - 6)
CGContextAddLineToPoint(context, self.bounds.width, 0)
CGContextAddLineToPoint(context, self.bounds.width, self.bounds.height)
CGContextAddLineToPoint(context, 0, self.bounds.height)
CGContextSetFillColorWithColor(context,UIColor(red: 37/255, green: 88/255, blue: 120/255, alpha: 1.0).CGColor)
CGContextDrawPath(context, CGPathDrawingMode.Fill)
How can I animate the blue part from left to right, while keeping the gray "max" portion of the graph always visible?
drawRect is producing still picture. To get animation you're saying about I'd recommend the following:
- Use CoreAnimation to produce animation
- Use UIBezierPath to make a shape you need
- Use CALayer's mask to animate within required shape
Here is example code for Playground:
import UIKit
import QuartzCore
import XCPlayground
let view = UIView(frame: CGRect(x: 0, y: 0, width: 120, height: 40))
XCPlaygroundPage.currentPage.liveView = view
let maskPath = UIBezierPath()
maskPath.moveToPoint(CGPoint(x: 10, y: 30))
maskPath.addLineToPoint(CGPoint(x: 10, y: 25))
maskPath.addLineToPoint(CGPoint(x: 100, y: 10))
maskPath.addLineToPoint(CGPoint(x: 100, y: 30))
maskPath.closePath()
let maskLayer = CAShapeLayer()
maskLayer.path = maskPath.CGPath
maskLayer.fillColor = UIColor.whiteColor().CGColor
let rectToAnimateFrom = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 97, height: 40))
let rectToAnimateTo = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 0, height: 40))
let layerOne = CAShapeLayer()
layerOne.path = maskPath.CGPath
layerOne.fillColor = UIColor.grayColor().CGColor
let layerTwo = CAShapeLayer()
layerTwo.mask = maskLayer
layerTwo.fillColor = UIColor.greenColor().CGColor
view.layer.addSublayer(layerOne)
view.layer.addSublayer(layerTwo)
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = rectToAnimateFrom.CGPath
animation.toValue = rectToAnimateTo.CGPath
animation.duration = 1
animation.repeatCount = 1000
animation.autoreverses = true
layerTwo.addAnimation(animation, forKey: "Nice animation")
In your code, I only see you draw the graphic once, why not draw gray part first and then draw the blue part.
I don't think it is efficient enough to implement animation in drawRect function.
You can take a look at Facebook's Shimmer Example, it simulate the effect of iPhone unlock animation. It uses a mask layer. The idea could also work in your example.
Also, Facebook's pop framework could simplify your work.