swift3 写字效果

           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
    }
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值