I want to achieve this type of animation.please check this URL
https://www.dropbox.com/s/gz9vfy5refsh7a5/Screen.mov?dl=0
I am adding Code which I have used in the project where I have used Core Graphics to render the text with animation but I am not able to animate text which is being shown in the mentioned link
This is code which i am using to render the text on the screen
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
context.setAlpha(noLightText)
let nOLIGHTRect = CGRect(x: 145.66, y: 590, width: 449.38, height: 125)
let nOLIGHTStyle = NSMutableParagraphStyle()
nOLIGHTStyle.alignment = .center
let nOLIGHTFontAttributes = [
.font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
.foregroundColor: nOLIGHTColor,
.paragraphStyle: nOLIGHTStyle,
] as [NSAttributedStringKey: Any]
"NO LIGHT".draw(in: nOLIGHTRect, withAttributes: nOLIGHTFontAttributes)
context.restoreGState()
//// LOW LIGHT Drawing
context.saveGState()
context.setAlpha(_0)
let lOWLIGHTRect = CGRect(x: 145.94, y: 590, width: 449.38, height: 125)
let lOWLIGHTStyle = NSMutableParagraphStyle()
lOWLIGHTStyle.alignment = .left
let lOWLIGHTFontAttributes = [
.font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
.foregroundColor: lOWLIGHTColor,
.paragraphStyle: lOWLIGHTStyle,
] as [NSAttributedStringKey: Any]
"LOW LIGHT".draw(in: lOWLIGHTRect, withAttributes: lOWLIGHTFontAttributes)
context.restoreGState()
//// MID LIGHT Drawing
context.saveGState()
context.setAlpha(mediumLightText)
let mIDLIGHTRect = CGRect(x: 145.77, y: 590, width: 449.38, height: 125)
let mIDLIGHTStyle = NSMutableParagraphStyle()
mIDLIGHTStyle.alignment = .left
let mIDLIGHTFontAttributes = [
.font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
.foregroundColor: mIDLIGHTColor,
.paragraphStyle: mIDLIGHTStyle,
] as [NSAttributedStringKey: Any]
"MID LIGHT".draw(in: mIDLIGHTRect, withAttributes: mIDLIGHTFontAttributes)
context.restoreGState()
If you want to animate the outline strokes of multiple characters at once you can:
- determine the CGPaths for each character
- map the CGPaths to CAShapeLayers
- animate the
strokeEnd
property
This would look like this:
Please note:
The fonts used by iOS are outline fonts using either the TrueType or OpenType format. That means that each glyph is using lines and curves to define its boundary. What we see normally when a glyph is rendered is the filled area. Therefore if the 'strokeEnd' property is animated then the outline of the glyph is drawn. The following code shows how this can be achieved.
Animation of the text in a way that a human being would write the text would be more effort (e. g. using a stroke font instead of an outline font plus associated engine or using user-defined vector paths representing each character)
var charLayers = [CAShapeLayer]()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for layer in self.charLayers {
layer.removeFromSuperlayer()
}
let stringAttributes = [ NSAttributedStringKey.font: UIFont(name: "Futura-CondensedExtraBold", size: 64.0)! ]
let attributedString = NSMutableAttributedString(string: "hello world", attributes: stringAttributes )
let charPaths = self.characterPaths(attributedString: attributedString, position: CGPoint(x: 24, y: 192))
self.charLayers = charPaths.map { path -> CAShapeLayer in
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 2
shapeLayer.path = path
return shapeLayer
}
for layer in self.charLayers {
view.layer.addSublayer(layer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.duration = 2.2
layer.add(animation, forKey: "charAnimation")
}
}
func characterPaths(attributedString: NSAttributedString, position: CGPoint) -> [CGPath] {
let line = CTLineCreateWithAttributedString(attributedString)
guard let glyphRuns = CTLineGetGlyphRuns(line) as? [CTRun] else { return []}
var characterPaths = [CGPath]()
for glyphRun in glyphRuns {
guard let attributes = CTRunGetAttributes(glyphRun) as? [String:AnyObject] else { continue }
let font = attributes[kCTFontAttributeName as String] as! CTFont
for index in 0..<CTRunGetGlyphCount(glyphRun) {
let glyphRange = CFRangeMake(index, 1)
var glyph = CGGlyph()
CTRunGetGlyphs(glyphRun, glyphRange, &glyph)
var characterPosition = CGPoint()
CTRunGetPositions(glyphRun, glyphRange, &characterPosition)
characterPosition.x += position.x
characterPosition.y += position.y
if let glyphPath = CTFontCreatePathForGlyph(font, glyph, nil) {
var transform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: characterPosition.x, ty: characterPosition.y)
if let charPath = glyphPath.copy(using: &transform) {
characterPaths.append(charPath)
}
}
}
}
return characterPaths
}