Last active
May 20, 2019 08:31
-
-
Save yycking/65086afff38ac437d39b0035934af3f4 to your computer and use it in GitHub Desktop.
手寫字
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var charLayers = [CAShapeLayer]() | |
override func viewDidAppear(_ animated: Bool) { | |
super.viewDidAppear(animated) | |
for layer in self.charLayers { | |
layer.removeFromSuperlayer() | |
} | |
let stringAttributes = [ NSAttributedString.Key.font: UIFont(name: "Zapfino", size: 32.0)! ] | |
let attributedString = NSMutableAttributedString(string: "Hello world!", attributes: stringAttributes ) | |
let charPaths = self.charactersPath(attributedString: attributedString) | |
let charSize = charPaths.bounds.size | |
let point = view.center | |
charPaths.apply(CGAffineTransform(translationX: point.x-charSize.width * 0.5, y: point.y*0.5)) | |
let shapeLayer = CAShapeLayer() | |
shapeLayer.fillColor = UIColor.clear.cgColor | |
shapeLayer.strokeColor = UIColor.red.cgColor | |
shapeLayer.lineWidth = 2 | |
shapeLayer.path = charPaths.cgPath | |
view.layer.addSublayer(shapeLayer) | |
let animation = CABasicAnimation(keyPath: "strokeEnd") | |
animation.fromValue = 0 | |
animation.duration = 2.2 | |
shapeLayer.add(animation, forKey: "charAnimation") | |
} | |
func charactersPath(attributedString: NSAttributedString) -> UIBezierPath { | |
let line = CTLineCreateWithAttributedString(attributedString) | |
guard let glyphRuns = CTLineGetGlyphRuns(line) as? [CTRun] else { return UIBezierPath()} | |
let characterPaths = CGMutablePath() | |
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) | |
if let glyphPath = CTFontCreatePathForGlyph(font, glyph, nil) { | |
let transform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: characterPosition.x, ty: characterPosition.y) | |
characterPaths.addPath(glyphPath, transform: transform) | |
} | |
} | |
} | |
return UIBezierPath(cgPath: characterPaths) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment