{"id":2142,"date":"2013-01-02T21:01:16","date_gmt":"2013-01-02T20:01:16","guid":{"rendered":"http:\/\/t-machine.org\/?p=2142"},"modified":"2013-12-23T16:01:26","modified_gmt":"2013-12-23T15:01:26","slug":"svgkit-2013-recipes","status":"publish","type":"post","link":"http:\/\/new.t-machine.org\/index.php\/2013\/01\/02\/svgkit-2013-recipes\/","title":{"rendered":"SVGKit 2013 &#8211; Recipes"},"content":{"rendered":"<p>SVG is an awesome image format thats widely used, works in all browsers. SVG graphics make better apps and better games &#8211; and automatically &#8220;upgrade&#8221; themselves for future devices.<\/p>\n<p>This post gives some simple 1-line \/ few lines of code recipes for using some of the main features of <a href=\"https:\/\/github.com\/SVGKit\/SVGKit\/\">SVGKit \u2013 SVG implementation for iOS\/OS X<\/a>.<\/p>\n<p><span style=\"color: blue\">NOTE: this post refers to the <a href=\"https:\/\/github.com\/SVGKit\/SVGKit\/tree\/1.0.1\">1.0.x version of SVGKit<\/a><\/span><\/p>\n<h3>Basic usage \/ installation<\/h3>\n<p>Install instructions are on the main GitHub page.<\/p>\n<p>Basic usage \/ first-time usage info is on <a href=\"http:\/\/t-machine.org\/index.php\/2012\/12\/31\/svgkit-2013-usage\/\">SVGKit 2013 &#8211; Usage<\/a>.<\/p>\n<h3>Recipes<\/h3>\n<h4>Load an SVG file like loading a PNG file<\/h4>\n<p>[objc]<br \/>\nSVGKImage* newImage = [SVGKImage imageNamed:@&quot;imagename&quot;];<br \/>\n[\/objc]<\/p>\n<h4>Display an SVG file on-screen using an ImageView<\/h4>\n<p>[objc]<br \/>\n[self.view addSubView: [[SVGKFastImageView alloc] initWithImage:newImage];<br \/>\n[\/objc]<\/p>\n<h4>&#8230;or an ImageView that supports CoreAnimation for every element<\/h4>\n<p>NB: the &#8220;Fast&#8221; imageview above saves everything as a single layer. Good for rendering, but bad for interaction. The &#8220;Layered&#8221; imageview here allows you to tap on any layer, rotate\/animate\/fade\/drop-shadow\/glow any element, etc.<\/p>\n<p>[objc]<br \/>\n[self.view addSubView:  [[SVGKLayeredImageView alloc] initWithImage:newImage];<br \/>\n[\/objc]<\/p>\n<h4>Use a URL to load an SVG (open an SVG file *directly* from the web)<\/h4>\n<p>[objc]<br \/>\n\/\/ Splitting URL to multiple lines to make blogpost<br \/>\n\/\/    easier to read&#8230;<br \/>\nNSString* longURL = [NSString stringWithFormat:@&quot;%@%@%@&quot;,<br \/>\n@&quot;http:\/\/upload.wikimedia.org\/&quot;,<br \/>\n@&quot;wikipedia\/commons\/f\/fd\/&quot;,<br \/>\n@&quot;Ghostscript_Tiger.svg&quot;;<br \/>\nNSURL* url = [NSURL urlWithString:longURL];<br \/>\nSVGKImage* newImage = [SVGKImage imageWithContentsOfURL:url];<br \/>\n[\/objc]<\/p>\n<h4>Open an SVG from a custom source (maybe an in-memory SVG creation method)<\/h4>\n<p>First, create a class that conforms to SVGKSourceReader, i.e.:<\/p>\n<p>[objc]<br \/>\n@interface MyNewClass : NSObject &lt;SVGKSourceReader&gt;<br \/>\n&#8230;<br \/>\n[\/objc]<\/p>\n<p>&#8230;then subclass SVGKSource, and over-ride the method:<\/p>\n<p>[objc]<br \/>\n-(NSObject&lt;SVGKSourceReader&gt;*) newReader:(NSError**) error<br \/>\n[\/objc]<\/p>\n<p>Finally, use your customized SVGKSource to load your SVG:<\/p>\n<p>[objc]<br \/>\nSVGKSource* myCustomSource = [[[MyCustomClass alloc] init] newReader:nil];<\/p>\n<p>\/** Other examples, using the default SVGKSource class:<br \/>\nSVGKSource* urlSource = [SVGKSource sourceFromURL: [NSURL &#8230;];<br \/>\nSVGKSource* fileSource = [SVGKSource sourceFromFilename: @&quot;monkey.svg&quot;];<br \/>\n*\/<\/p>\n<p>SVGKImage* newImage = [SVGKImage imageWithSource:myCustomSource];<br \/>\n[\/objc]<\/p>\n<h4>Search an SVG file for particular tags \/ nodes \/ elements<\/h4>\n<p>SVG is an XML file, containing XML tags\/nodes such as: &#8220;&lt;svg&gt;&#8221;, &#8220;&lt;g&gt;&#8221;, &#8220;&lt;path&gt;&#8221;, &#8220;&lt;linearGradient&gt;&#8221;, etc.<\/p>\n<p>[objc]<br \/>\nNSString* tagToFind = @&quot;linearGradient&quot;;<br \/>\nNodeList* result = [svgImage.DOMDocument getElementsByTagName:tagToFind];<\/p>\n<p>for( Element* domElement in result )<br \/>\n{<br \/>\n   \/\/ You can use the Element object directly:<br \/>\n   domElement.tagName;<br \/>\n   &#8230;<\/p>\n<p>   \/\/ &#8230;or, if it was parsed by the SVG parser, you can convert it to an SVGElement:<br \/>\n   SVGElement* svgElement = (SVGElement*) domElement;<br \/>\n   &#8230;<br \/>\n}<br \/>\n[\/objc]<\/p>\n<h4>Search for sub-tags \/ sub-nodes of a particular tag\/node<\/h4>\n<p>If you already have an SVGElement reference, you can search all its descendants:<\/p>\n<p>[objc]<br \/>\n\/\/ To search the entire document, use:<\/p>\n<p>\/\/ SVGElement* startPoint = newImage.DOMTree;<br \/>\nSVGElement* startPoint = &#8230; \/\/ from your code<\/p>\n<p>NSString* tagToFind = @&quot;linearGradient&quot;;<br \/>\nNodeList* result = [startPoint getElementsByTagName:tagToFind];<\/p>\n<p>for( Element* domElement in result )<br \/>\n{<br \/>\n   SVGElement* svgElement = (SVGElement*) domElement; \/\/ if your tags are all supported by SVGKit, they will be converted to SVGElement instances<br \/>\n   &#8230;<br \/>\n}<br \/>\n[\/objc]<\/p>\n<h4>Get a list of ALL descendant tags (from a particular node down)<\/h4>\n<p>[objc]<br \/>\nSVGElement* startPoint = &#8230; \/\/ e.g. for whole SVG doc, use: newImage.DOMDocument;<br \/>\nNodeList* allElements = [startPoint getElementsByTagName:@&quot;*&quot;];<br \/>\n[\/objc]<\/p>\n<h4>Render one small part of the SVG file on its own<\/h4>\n<p>E.g. if you want to display a subset of the SVG, or want to export a single element:<br \/>\n[objc]<br \/>\nNSString* idInSVGFile = &#8230; \/\/ assuming your SVG file has an &quot;id&quot; attribute for this node<br \/>\nCALayer* absoluteLayer = [newImage newCopyPositionedAbsoluteLayerWithIdentifier:isInSVGFile];<\/p>\n<p>&#8230;<\/p>\n<p>\/\/ NB: &quot;absoluteLayer&quot; is now positioned in absolute space;<br \/>\n\/\/   if you add it to your window using e.g.:<br \/>\n[self.view.layer addSublayer: absoluteLayer];<br \/>\n\/\/ &#8230;it will appear in the same place as it appeared before,<br \/>\n\/\/   keeping all the offsets, rotations, etc<br \/>\n[\/objc]<\/p>\n<p><span style=\"color: blue\">NOTE: there are several &#8220;newCopy&#8230;&#8221; methods, and each has different effects and outcomes. Read the method docs for each to decide which one you want to use. In a future version of SVGKit, we&#8217;d like to move these methods into a class of their own, and make it easier to see which one does what<\/span><\/p>\n<h4>Customise the parsing, using your own parser extensions<\/h4>\n<p>Create your custom class that adheres to SVGKParserExtension:<br \/>\n[objc]<br \/>\n@interface MyCustomSVGParserExtension : NSObject &lt;SVGKParserExtension&gt;<br \/>\n&#8230;<br \/>\n[\/objc]<br \/>\nThen create a parser, INCLUDE THE DEFAULT extensions, and add your one on the end:<br \/>\n[objc]<br \/>\nMyCustomSVGParserExtension* myCustomExtension = [[MyCustomSVGParserExtension alloc] init];<\/p>\n<p>SVGKParser* parser = [[SVGKParser alloc] init];<br \/>\n[parser addDefaultSVGParserExtensions]; \/\/ HIGHLY RECOMMENDED<br \/>\n[parser addParserExtension:myCustomExtension];<\/p>\n<p>SVGKParseResult* result = [parser parseSynchronously];<\/p>\n<p>SVGKImage* newImage = [[SVGKImage alloc] initWithParsedSVG:result];<br \/>\n[\/objc]<\/p>\n<h4>Get help on why parsing failed (and warnings and line numbers!)<\/h4>\n<p>[objc]<br \/>\nSVGKImage* newImage = &#8230; \/\/ use methods above<\/p>\n<p>\/\/ EITHER: parse using default parser:<br \/>\nSVGKParseResult* parseResult1 = newImage.parseErrorsAndWarnings; \/\/ this is a convenience pointer to (SVGKParser*).currentParseRun<\/p>\n<p>\/\/ OR: use a custom parser:<br \/>\nSVGKParser* parser = &#8230; \/\/ use methods above<br \/>\nSVGKParseResult* parseResult2 = parser.currentParseRun;<br \/>\n[\/objc]<\/p>\n<p>And then you have the following info:<br \/>\n[objc]<br \/>\n\/*  array of NSError objects, each one a &quot;WARNING&quot; from the parser *\/<br \/>\nparseResult.warnings;<\/p>\n<p>\/* array of NSError objects, each one a &quot;FATAL ERROR&quot; from the parser &#8211; if your SVG didn&#8217;t render at all, this is why! *\/<br \/>\nparseResult.errorsFatal;<\/p>\n<p>\/* array of NSError objects, each one a &quot;RECOVERABLE ERROR&quot; from the parser &#8211; if your SVG didn&#8217;t render correctly, this is why! (although you probably still got to see something) *\/<br \/>\nparseResult.errorsRecoverable;<br \/>\n[\/objc]<\/p>\n<h2>UPDATE: more Recipes!<\/h2>\n<p>For more recipes, see <a href=\"http:\/\/t-machine.org\/index.php\/2013\/06\/01\/svgkit-2013-recipes-part-2\/\">SVGKit Recipes part 2<\/a><\/p>\n<p>(this covers answers to some of the common questions asked in the Comments below)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>SVG is an awesome image format thats widely used, works in all browsers. SVG graphics make better apps and better games &#8211; and automatically &#8220;upgrade&#8221; themselves for future devices. This post gives some simple 1-line \/ few lines of code recipes for using some of the main features of SVGKit \u2013 SVG implementation for iOS\/OS [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"_links":{"self":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts\/2142"}],"collection":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/comments?post=2142"}],"version-history":[{"count":6,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts\/2142\/revisions"}],"predecessor-version":[{"id":3053,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts\/2142\/revisions\/3053"}],"wp:attachment":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/media?parent=2142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/categories?post=2142"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/tags?post=2142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}