![[swift]读取svg图片为UIBezierPath,开心做动画,第1张 [swift]读取svg图片为UIBezierPath,开心做动画,第1张](/aiimages/%5Bswift%5D%E8%AF%BB%E5%8F%96svg%E5%9B%BE%E7%89%87%E4%B8%BAUIBezierPath%EF%BC%8C%E5%BC%80%E5%BF%83%E5%81%9A%E5%8A%A8%E7%94%BB.png)
给对本文感兴趣的朋友们推荐个好东西: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(_:)` 两个方法用于处理解析结果:
class VIEwController: 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="12" fill="black"/>
的标签转换成 CGRect 保存在数组中,并在 parserDIDEnddocument(_:) 中把他们转换为 CAShapeLayer 并添加动画。
先来看看 parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:) 的内容:
...var rects = [CGRect]() // 用于存储二维码func parser(parser: NSXMLParser!,attributes attributeDict: [NSObject : AnyObject]!) { // 只转换 “黑色” 的二维码 “方块” 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["wIDth"] as Nsstring).doubleValue let h = (attributeDict["height"] as Nsstring).doubleValue qrVIEw.bounds = CGRect(x: 0,y: 0,height: h) }}... 接下来是 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,0) // 沿 y 轴旋转 π/2 圈,待会再动画转回来 // transform 动画 let transAnim = CABasicAnimation(keyPath: "transform") transAnim.duration = drand48() * 4 // 随机一个持续时间 transAnim.fromValue = NSValue(CAtransform3D: starttransform) transAnim.tovalue = NSValue(CAtransform3D: CAtransform3DIDentity) rectLayer.addAnimation(transAnim,forKey: "transAnim") // 透明度动画 let AlphaAnim = CABasicAnimation(keyPath: "opacity") AlphaAnim.duration = transAnim.duration AlphaAnim.fromValue = 0 AlphaAnim.tovalue = 1 rectLayer.addAnimation(AlphaAnim,forKey: "AlphaAnim") qrVIEw.layer.addSublayer(rectLayer) }} 完工
没眼看,不录gif了。。。心塞。。。
继续加特技手贱没忍住。。。二维码真是玩不坏。。。
总结
以上是内存溢出为你收集整理的[swift]读取svg图片为UIBezierPath,开心做动画全部内容,希望文章能够帮你解决[swift]读取svg图片为UIBezierPath,开心做动画所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)