[swift]读取svg图片为UIBezierPath,开心做动画

[swift]读取svg图片为UIBezierPath,开心做动画,第1张

概述https://segmentfault.com/a/1190000002580541 更新 给对本文感兴趣的朋友们推荐个好东西:paintcode 动画预览 先扯淡 最近手痒又想整点动画玩玩,但是想了几个主意发现稍微复杂一点的手写都一定会累爆。这篇文章记录一下今天折腾的一个方案。说来简单,就是用矢量设计工具舒舒服服的做好设计,然后输出成 svg 格式,再用 NSXMLParser 去读出来,转换

https://segmentfault.com/a/1190000002580541


更新

给对本文感兴趣的朋友们推荐个好东西:paintcode

动画预览

先扯淡

最近手痒又想整点动画玩玩,但是想了几个主意发现稍微复杂一点的手写都一定会累爆。这篇文章记录一下今天折腾的一个方案。说来简单,就是用矢量设计工具舒舒服服的做好设计,然后输出成svg格式,再用NSXMLParser去读出来,转换成UIBezIErPath,然后就天高任鸟飞~

清晰起见,这里不使用各种库,由上面的二维码动画为例,只转换最简单的矩形。需要更多高能 *** 作的,出门右转SVGKit。

开工

筹备材料先,首先找个能提供svg格式下载的二维码生成网站,比如这个。拿到svg文件后用文本编辑器打开可以看到其实是一个描述矢量图形的xml,而且里面几百个矩形。。。如果你用的生成网站跟我一样,还会有一个白色的背景矩形,待会儿我们会把它排除掉。

准备工作就到这了,接下来我们会用NSXMLParser来解析这个二维码。

新建一个Single VIEw Application,把二维码拖进项目里去,在VIEwController里添加一个UIVIEw作为二维码的容器:

class VIEwController: UIVIEwController {    let qrVIEw = UIVIEw()    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()                qrVIEw.center = vIEw.center        vIEw.addSubvIEw(qrVIEw)    }        ...}

初始化一个NSXMLParser去解析svg,同时让VIEwController实现NSXMLParserDelegate`
parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:)
parserDIDEnddocument(_:)`两个方法用于处理解析结果:

UIVIEwController,NSXMLParserDelegate {        ...        overrIDe func vIEwDIDLoad() {        ...                let qrPath = NSBundle.mainBundle().pathForResource("zcfan_qrcode",ofType: "svg")!        let qrData = NSData(contentsOffile: qrPath)        let xmlParser = NSXMLParser(data: qrData)        xmlParser.delegate = self        xmlParser.parse()    }        func parser(parser: NSXMLParser!,dIDStartElement elementname: String!,namespaceURI: String!,qualifIEdname qname: String!,attributes attributeDict: [NSObject : AnyObject]!) {        // 每当解析到一个新标签,这里就会被调用    }        func parserDIDEnddocument(parser: NSXMLParser!) {        // 整个 svg 文件解析完毕后,这里就会被调用    }        ...}

接下来我们会在parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:)中把遇到的每一个形如:

<rect... x="0"y="0"wIDth="12"height=fill="black"/>

的标签转换成CGRect保存在数组中,并在parserDIDEnddocument(_:)中把他们转换为CAShapeLayer并添加动画。

先来看看parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:)的内容:

...var rects = [CGRect]()  // 用于存储二维码func // 只转换 “黑色” 的二维码 “方块”    if elementname == "rect" && (attributeDict["fill"] as String) == "black" {        let x = (attributeDict["x"] as Nsstring).doubleValue        let y = (attributeDict["y"] as Nsstring).doubleValue        let w = (attributeDict["wIDth"] as Nsstring).doubleValue        let h = (attributeDict["height"] as Nsstring).doubleValue                let rect = CGRect(x: x,y: y,wIDth: w,height: h)        rects.append(rect)            // 设置 qrVIEw 的尺寸为 svg 图像的大小    } else if elementname == "svg" {        let w = (attributeDict[Nsstring).doubleValue                qrVIEw.bounds = CGRect(x: 0,y:  接下来是parserDIDEnddocument(_:),在这里我们要把二维码显示出来:

...func parserDIDEnddocument(parser: NSXMLParser!) {    for r in rects {        let rectLayer = CAShapeLayer()                rectLayer.fillcolor = UIcolor.darkGraycolor().CGcolor        rectLayer.strokecolor = nil        rectLayer.path = UIBezIErPath(rect: CGRect(origin: CGPointZero,size: r.size)).CGPath  // #1        rectLayer.frame = r  // #2                qrVIEw.layer.addSublayer(rectLayer)    }}...

#1#2:看着有点晕?代码不直观的话不妨稍微把玩一下,原因很简单,但要用语言解释我的舌头可能会打结。。。

至此,运行项目应该就能在屏幕上看到一个大二维码了!

加特技! Duang~

回到上面的parserDIDEnddocument(_:)方法,然后把它改到面目全非!Duang~

func parserDIDEnddocument(parser: NSXMLParser!) {        qrVIEw.layer.shadowcolor = UIcolor.graycolor().CGcolor    qrVIEw.layer.shadowRadius = 4    qrVIEw.layer.shadowOpacity = 1    qrVIEw.layer.shadowOffset = CGSizeZero        for r in rects {        let rectLayer = CAShapeLayer()                rectLayer.fillcolor = UIcolor.darkGraycolor().CGcolor        rectLayer.strokecolor = nil        rectLayer.path = UIBezIErPath(rect: CGRect(origin: CGPointZero,size: r.size)).CGPath        rectLayer.frame = r                var starttransform = CAtransform3DIDentity        starttransform.m34 = 1.0 / -20  // 透视        starttransform = CAtransform3DRotate(starttransform,CGfloat(M_PI)*0.5,1,128)">0)  // 沿 y 轴旋转 π/2 圈,待会再动画转回来                // transform 动画        let transAnim = CABasicAnimation(keyPath: "transform")        transAnim.duration = drand48() * 4  // 随机一个持续时间        transAnim.fromValue = NSValue(CAtransform3D: starttransform)        transAnim.tovalue = CAtransform3D: CAtransform3DIDentity)        rectLayer.addAnimation(transAnim,forKey: "transAnim")                // 透明度动画        let AlphaAnim = "opacity")        AlphaAnim.duration = transAnim.duration        AlphaAnim.fromValue = 0        AlphaAnim.tovalue = 1        rectLayer.addAnimation(AlphaAnim,68)">"AlphaAnim")                qrVIEw.layer.addSublayer(rectLayer)    }}
完工

没眼看,不录gif了。。。心塞。。。

继续加特技

手贱没忍住。。。二维码真是玩不坏。。。

总结

以上是内存溢出为你收集整理的[swift]读取svg图片为UIBezierPath,开心做动画全部内容,希望文章能够帮你解决[swift]读取svg图片为UIBezierPath,开心做动画所遇到的程序开发问题。

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存