将String转换为其表示的路径画到屏幕上

将String转换为其表示的路径画到屏幕上,第1张

概述关于这个问题,我已经在另一篇blog中有所提及: CoreText精彩文字轮廓绘制动画的一点改进 不过原有的转换代码使用Obj-C写的,在这里我们尝试将其转换为Swift语言,然后利用它实现一个测试小程序. 首先贴出原来Objc的代码: - (void) setupTextLayer{ if (self.pathLayer != nil) { [self.penLayer

关于这个问题,我已经在另一篇blog中有所提及:

CoreText精彩文字轮廓绘制动画的一点改进

不过原有的转换代码使用Obj-C写的,在这里我们尝试将其转换为Swift语言,然后利用它实现一个测试小程序.

首先贴出原来Objc的代码:

- (voID) setupTextLayer{    if (self.pathLayer != nil) {        [self.penLayer removeFromSuperlayer];        [self.pathLayer removeFromSuperlayer];        self.pathLayer = nil;        self.penLayer = nil;    }    // Create path from text    // See: http://www.codeproject.com/KB/iPhone/Glyph.aspx    // license: The Code Project Open license (CPol) 1.02 http://www.codeproject.com/info/cpol10.aspx    CGMutablePathref letters = CGPathCreateMutable();    CTFontRef Font = CTFontCreateWithname(CFSTR("Helvetica-Bold"),72.0f,NulL);    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:                           (ID)Font,kCTFontAttributename,nil];    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"你好,大熊猫侯佩!"    //NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"Hello World!"                                                                     attributes:attrs];    CTlineRef line = CTlineCreateWithAttributedString((CFAttributedStringRef)attrString);    CFArrayRef runArray = CTlineGetGlyphRuns(line);    // for each RUN    for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)    {        // Get Font for this run        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray,runIndex);        CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run),kCTFontAttributename);        // for each GLYPH in run        for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++)         {            // get Glyph & Glyph-data            CFRange thisGlyphRange = CFRangeMake(runGlyphIndex,1);            CGGlyph glyph;            CGPoint position;            CTRunGetGlyphs(run,thisGlyphRange,&glyph);            CTRunGetpositions(run,&position);            // Get PATH of outline            {                CGPathref letter = CTFontCreatePathForGlyph(runFont,glyph,NulL);                CGAffinetransform t = CGAffinetransformMakeTranslation(position.x,position.y);                CGPathAddpath(letters,&t,letter);                CGPathRelease(letter);            }        }    }    CFRelease(line);    UIBezIErPath *path = [UIBezIErPath bezIErPath];    [path movetoPoint:CGPointZero];    [path appendpath:[UIBezIErPath bezIErPathWithCGPath:letters]];    CGPathRelease(letters);    CFRelease(Font);    CAShapeLayer *pathLayer = [CAShapeLayer layer];    pathLayer.frame = self.animationLayer.bounds;    pathLayer.bounds = CGPathGetBoundingBox(path.CGPath);    //pathLayer.backgroundcolor = [[UIcolor yellowcolor] CGcolor];    pathLayer.geometryFlipped = YES;    pathLayer.path = path.CGPath;    pathLayer.strokecolor = [[UIcolor blackcolor] CGcolor];    pathLayer.fillcolor = nil;    pathLayer.linewidth = 5.0f;    //pathLayer.lineJoin = kCAlineJoinBevel;    pathLayer.lineJoin = kCAlineJoinMiter;    [self.animationLayer addSublayer:pathLayer];    self.pathLayer = pathLayer;    //happy commit    NSLog(@"Hello World!!!");    //UIImage *penImage = [UIImage imagenamed:@"noun_project_347_2.png"];    UIImage *penImage = [UIImage imagenamed:@"bee.png"];    CALayer *penLayer = [CALayer layer];    penLayer.contents = (ID)penImage.CGImage;    penLayer.anchorPoint = CGPointZero;    penLayer.frame = CGRectMake(0.0f,0.0f,penImage.size.wIDth/5,penImage.size.height/5);    [pathLayer addSublayer:penLayer];    self.penLayer = penLayer;}

看起来颇长啊!不过不要太在意,因为我们要用Swift重写的代码只提取其中中间的一部分,这样可以更好的重用.

新建一个项目,基于Swift语言.

在项目中新建一个Swift源代码文件,该文件扩展了String类,我们在其扩展中先写一个帮助方法的存根:

extension String{    func topath(Font:CTFont)->CGPath{    }}

topath方法用来实现任意String实例到CGPath路径的转换,在其中添加如下内容:

let letters:CGMutablePathref = CGPathCreateMutable()        let attrs = [kCTFontAttributename as String:Font]        let attrString:NSAttributedString = NSAttributedString(string: self,attributes: attrs)        let line:CTline = CTlineCreateWithAttributedString(attrString)        let runArray = CTlineGetGlyphRuns(line)        for runIndex in 0..<CFArrayGetCount(runArray){            let run = CFArrayGetValueAtIndex(runArray,runIndex)            let runb = unsafeBitCast(run,CTRun.self)            //let runFont:CTFont = CFDictionaryGetValue(CTRunGetAttributes(runb),kCTFontAttributename as String) as! CTFont            let CTFontname = unsafeBitCast(kCTFontAttributename,UnsafePointer<VoID>.self)            let runFontC = CFDictionaryGetValue(CTRunGetAttributes(runb),CTFontname)            let runFont = unsafeBitCast(runFontC,CTFont.self)            //for each GLYPH in run            for runGlyphIndex in 0..<CTRunGetGlyphCount(runb){                //get Glyph & Glyph-data                let glyphRange = CFRange(location: runGlyphIndex,length: 1)                //let glyph:UnsafeMutablePointer<CGGlyph> = UnsafeMutablePointer<CGGlyph>.alloc(1)                //glyph.initialize(0)                var glyph:CGGlyph = 0                let position:UnsafeMutablePointer<CGPoint> = UnsafeMutablePointer<CGPoint>.alloc(1)                position.initialize(CGPoint.zero)                CTRunGetGlyphs(runb,glyphRange,&glyph)                CTRunGetpositions(runb,position)                //Get PATH of outline                //let letter = CTFontCreatePathForGlyph(runFont,glyph.memory,nil)                let letter = CTFontCreatePathForGlyph(runFont,nil)                var t = CGAffinetransformMakeTranslation(position.memory.x,position.memory.y)                //let tx:UnsafeMutablePointer<CGAffinetransform> = UnsafeMutablePointer<CGAffinetransform>.alloc(1)                //tx.initialize(t)                CGPathAddpath(letters,letter)                //CGPathRelease(letter)                position.destroy()                position.dealloc(1)            }        }        let path = UIBezIErPath()        path.movetoPoint(CGPoint.zero)        path.appendpath(UIBezIErPath(CGPath: letters))        return path.CGPath

大家可以对照原来的Obj-c版本看一下,大致都是一一对应的,只有少数几个涉及 *** 作C语言数据的地方有修改,大家可以参考我写的另一篇blog:

Swift中如何转换不同类型的Mutable指针

核心功能有了,下面就好办了!我们想要的是点击屏幕开始显示动画,于是重载如下方法:

overrIDe func touchesEnded(touches: Set<UItouch>,withEvent event: UIEvent?) {        if isAnimating { return }        isAnimating = true        flyerLayer.opacity = 0.8        pathLayer.removeAllAnimations()        flyerLayer.removeAllAnimations()        let strokeAnimation = CABasicAnimation(keyPath: "strokeEnd")        strokeAnimation.duration = 20.0        strokeAnimation.fromValue = 0.0        strokeAnimation.tovalue = 1.0        strokeAnimation.delegate = self        pathLayer.addAnimation(strokeAnimation,forKey: nil)        let flyAnimation = CAKeyframeAnimation(keyPath: "position")        flyAnimation.duration = 20.0        flyAnimation.path = pathLayer.path        flyAnimation.calculationMode = kCAAnimationPaced        flyerLayer.addAnimation(flyAnimation,forKey: nil)    }

下面是App实际运行的效果:

总结

以上是内存溢出为你收集整理的将String转换为其表示的路径画到屏幕上全部内容,希望文章能够帮你解决将String转换为其表示的路径画到屏幕上所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1075233.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存