let textLayer: CAShapeLayer = CAShapeLayer.init()
textLayer.fillColor = UIColor.clear.cgColor
textLayer.strokeColor = UIColor.white.cgColor
textLayer.lineWidth = 1
textLayer.lineCap = kCALineCapButt
containerView.layer.addSublayer(textLayer)
let textAnimation = CABasicAnimation.init(keyPath: "strokeEnd")
textAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
textAnimation.fromValue = NSNumber.init(value: 0)
textAnimation.toValue = NSNumber.init(value: 1)
textAnimation.duration = 2.0
textAnimation.repeatCount = HUGE
textAnimation.isRemovedOnCompletion = false
textLayer.add(textAnimation, forKey: "")
let attributed: NSMutableAttributedString = NSMutableAttributedString(string: "Loading...")
attributed.addAttributes([NSFontAttributeName : UIFont.systemFont(ofSize: 12)], range: NSRange.init(location: 0, length: attributed.string.characters.count))
textLayer.path = textPath(text: attributed).cgPath
复制代码
func textPath(text: NSMutableAttributedString) -> UIBezierPath {
let letters: CGMutablePath = CGMutablePath()
let line: CTLine = CTLineCreateWithAttributedString(text as CFAttributedString)
let runArray: CFArray = CTLineGetGlyphRuns(line)
for runIndex: CFIndex in 0..<CFArrayGetCount(runArray) {
let run = CFArrayGetValueAtIndex(runArray, runIndex)
let runb = unsafeBitCast(run, to: CTRun.self)
let CTFontName = unsafeBitCast(kCTFontAttributeName, to: UnsafeRawPointer.self)
let runFontC = CFDictionaryGetValue(CTRunGetAttributes(runb),CTFontName)
let runFontS: CTFont = unsafeBitCast(runFontC, to: CTFont.self)
for runGlyphIndex: CFIndex in 0..<CTRunGetGlyphCount(runb) {
let thisGlyphRange: CFRange = CFRangeMake(runGlyphIndex, 1)
let glyph: UnsafeMutablePointer<CGGlyph> = UnsafeMutablePointer<CGGlyph>.allocate(capacity: 1)
glyph.initialize(to: 0)
let position: UnsafeMutablePointer<CGPoint> = UnsafeMutablePointer<CGPoint>.allocate(capacity: 1)
position.initialize(to: CGPoint.zero)
CTRunGetGlyphs(runb, thisGlyphRange, glyph)
CTRunGetPositions(runb, thisGlyphRange, position)
let letter: CGPath = CTFontCreatePathForGlyph(runFontS, glyph.pointee, nil)!
let t: CGAffineTransform = CGAffineTransform(translationX: position.pointee.x, y: position.pointee.y)
letters.addPath(letter, transform: t)
glyph.deinitialize()
glyph.deallocate(capacity: 1)
position.deinitialize()
position.deallocate(capacity: 1)
let path: UIBezierPath = UIBezierPath.init(cgPath: letters)
let boundingBox: CGRect = letters.boundingBox
path.apply(CGAffineTransform(scaleX: 1.0, y: -1.0))
path.apply(CGAffineTransform(translationX: 0.0, y: boundingBox.size.height))
return path
private func bezierPathFrom(string: String) -> UIBezierPath? {
let paths = CGMutablePath()
let fontName = __CFStringMakeConstantString("MicrosoftYaHei")
let fontRef:AnyObject = CTFontCreateWithName(fontName, 14, nil)
let attrString = NSAttributedString(string: string, attributes: [kCTFontAttributeName as String : fontRef])
let line = CTLineCreateWithAttributedString(attrString as CFAttributedString)
let runA = CTLineGetGlyphRuns(line)
for runIndex: CFIndex in 0 ..< CFArrayGetCount(runA) {
let run = CFArrayGetValueAtIndex(runA, runIndex)
let runb = unsafeBitCast(run, to: CTRun.self)
let CTFontName = unsafeBitCast(kCTFontAttributeName, to: UnsafeRawPointer.self)
let runFontC = CFDictionaryGetValue(CTRunGetAttributes(runb),CTFontName)
let runFontS = unsafeBitCast(runFontC, to: CTFont.self)
let width = UIScreen.main.bounds.width
var temp = 0
var offset:CGFloat = 0.0
for i in 0 ..< CTRunGetGlyphCount(runb){
let range = CFRangeMake(i, 1)
let glyph:UnsafeMutablePointer<CGGlyph> = UnsafeMutablePointer<CGGlyph>.allocate(capacity: 1)
glyph.initialize(to: 0)
let position:UnsafeMutablePointer<CGPoint> = UnsafeMutablePointer<CGPoint>.allocate(capacity: 1)
position.initialize(to: CGPoint.zero)
CTRunGetGlyphs(runb, range, glyph)
CTRunGetPositions(runb, range, position);
let temp3 = CGFloat(position.pointee.x)
let temp2 = (Int) (temp3 / width)
let temp1 = 0
if(temp2 > temp1){
temp = temp2
offset = position.pointee.x - (CGFloat(temp) * width)
let path = CTFontCreatePathForGlyph(runFontS,glyph.pointee,nil)
let x = position.pointee.x - (CGFloat(temp) * width) - offset
let y = position.pointee.y - (CGFloat(temp) * 80)
let transform = CGAffineTransform(translationX: x, y: y)
paths.addPath(path!, transform: transform)
glyph.deinitialize()
glyph.deallocate(capacity: 1)
position.deinitialize()
position.deallocate(capacity: 1)
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint.zero)
bezierPath.append(UIBezierPath.init(cgPath: paths))
return bezierPath
安装掘金浏览器插件
多内容聚合浏览、多引擎快捷搜索、多工具便捷提效、多模式随心畅享,你想要的,这里都有!