Skip to content

Instantly share code, notes, and snippets.

@dobster
Created June 3, 2017 00:03
Show Gist options
  • Save dobster/f32e79fdefe3d0bf40fd2725123231b8 to your computer and use it in GitHub Desktop.
Save dobster/f32e79fdefe3d0bf40fd2725123231b8 to your computer and use it in GitHub Desktop.
Animating change to mask layer for iOS UIView
import UIKit
class CircleFillView: UIView {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
let circleLayer = CAShapeLayer()
let circleMaskLayer = CAShapeLayer()
private func commonInit() {
self.backgroundColor = .clear
circleLayer.fillColor = UIColor.black.cgColor
self.layer.addSublayer(circleLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
circleLayer.path = UIBezierPath(ovalIn: self.bounds).cgPath
}
private func fillPath(for percent: Double) -> CGPath {
let height = self.bounds.height * CGFloat(percent)
let rect = CGRect(x: 0, y: height, width: self.bounds.width, height: self.bounds.height - height)
return UIBezierPath(rect: rect).cgPath
}
/// Change fill color using implicit animation.
func implicitChange() {
circleLayer.fillColor = UIColor.blue.cgColor
}
/// Alter a mask to hide more of the circle. Animate the change with a custom duration.
func animatedChange() {
circleMaskLayer.path = fillPath(for: 0.0)
circleLayer.mask = circleMaskLayer
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 0.5
animation.fromValue = fillPath(for: 0.0)
animation.toValue = fillPath(for: 0.75)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
circleLayer.mask?.add(animation, forKey: "path")
(circleLayer.mask as? CAShapeLayer)?.path = fillPath(for: 0.75)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment