<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Free Time Studios &#187; Nathan Eror</title>
	<atom:link href="http://www.freetimestudios.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.freetimestudios.com</link>
	<description></description>
	<lastBuildDate>Mon, 09 Jan 2012 18:52:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>iPad and iOS 4 Custom Font Loading</title>
		<link>http://www.freetimestudios.com/2010/09/20/ipad-and-ios-4-custom-font-loading/</link>
		<comments>http://www.freetimestudios.com/2010/09/20/ipad-and-ios-4-custom-font-loading/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 06:17:22 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Text]]></category>
		<category><![CDATA[idevblogaday]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=970</guid>
		<description><![CDATA[Based on the response I received to my last post about Custom Fonts on the iPad and iOS 4, iOS font handling and Core Text are a bit of a mystery to many iOS developers. Because of that, I&#8217;ll focus on Core Text for my next few #idevblogaday posts. This week, the spotlight is on [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F09%2F20%2Fipad-and-ios-4-custom-font-loading%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F09%2F20%2Fipad-and-ios-4-custom-font-loading%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><div class="document">


<p>Based on the response I received to my last post about <a class="reference external" href="http://www.freetimestudios.com/2010/09/13/custom-fonts-on-the-ipad-and-ios-4/">Custom Fonts on the iPad and iOS 4</a>, iOS font handling and Core
Text are a bit of a mystery to many iOS developers. Because of that, I&#8217;ll focus on Core Text for my next few
<a class="reference external" href="http://idevblogaday.com/">#idevblogaday</a> posts. This week, the spotlight is on loading and configuring fonts to be drawn with Core Text or
<tt class="docutils literal">CATextLayer</tt>.</p>
<div class="section" id="registering-custom-fonts-with-ios">
<h2>Registering Custom Fonts With iOS</h2>
<p>Last week, I explained how to <a class="reference external" href="http://www.freetimestudios.com/2010/09/13/custom-fonts-on-the-ipad-and-ios-4/#load-the-font-into-memory">load a font directly from a file</a> using Quartz data providers. While this is a perfectly
acceptable way to load a custom font, it is no longer necessary. In iOS 3.2, a new key was added to <tt class="docutils literal">Info.plist</tt>
called <tt class="docutils literal">UIAppFonts</tt> (special thanks to <a class="reference external" href="http://twitter.com/hanspinckaers">&#64;hanspinckaers</a> and Ilari Sani for reminding me it exists). This little gem
takes an array of font file names, and it makes the named fonts available through the normal font loading mechanism.
This means you can finally use <a class="reference external" href="http://bancomicsans.com/main/">Comic Sans</a> instead of <a class="reference external" href="http://twitter.com/hotdogsladies/status/144893542">Marker Felt</a> in your apps.</p>
<p>Using <tt class="docutils literal">UIAppFonts</tt> is very simple. First, you need to make sure your font files are in your app bundle. Then, add the
<tt class="docutils literal">UIAppFonts</tt> key to your <tt class="docutils literal">Info.plist</tt>, and add an entry in the array for each font file you want available to your
app.</p>
<img alt="http://www.freetimestudios.com/wp-content/uploads/2010/09/UIAppFonts.png" class="aligncenter" src="http://www.freetimestudios.com/wp-content/uploads/2010/09/UIAppFonts.png" />
<p>Provided your font is one of the <a class="reference external" href="https://developer.apple.com/library/ios/#documentation/Carbon/Reference/CTFontDescriptorRef/Reference/reference.html#//apple_ref/doc/uid/TP40005107-CH4-SW12">supported font types</a>, it should now be available to load like any system font. The
following line of code uses Core Text to load our font:</p>
<div class="highlight"><pre><span class="n">CTFontRef</span> <span class="n">canHazComicSans</span> <span class="o">=</span>
  <span class="n">CTFontCreateWithName</span><span class="p">(</span><span class="n">CFSTR</span><span class="p">(</span><span class="s">&quot;ComicSans&quot;</span><span class="p">),</span> <span class="mf">24.f</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</pre></div>
</div>
<div class="section" id="next-week-configuring-font-attributes">
<h2>Next Week: Configuring Font Attributes</h2>
<p>Core Text fonts are very configurable. The power lies in <tt class="docutils literal">CTFontDescriptor</tt>, and it will be our topic next week.
Here&#8217;s a little code teaser to whet your appetite:</p>
<div class="highlight"><pre><span class="n">NSDictionary</span> <span class="o">*</span><span class="n">fontAttributes</span> <span class="o">=</span>
  <span class="p">[</span><span class="n">NSDictionary</span> <span class="nl">dictionaryWithObjectsAndKeys:</span>
    <span class="s">@&quot;Courier&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="n">kCTFontFamilyNameAttribute</span><span class="p">,</span>
    <span class="s">@&quot;Bold&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="n">kCTFontStyleNameAttribute</span><span class="p">,</span>
    <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithFloat:</span><span class="mf">16.f</span><span class="p">],</span> <span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="n">kCTFontSizeAttribute</span><span class="p">,</span>
    <span class="nb">nil</span><span class="p">];</span>
<span class="n">CTFontDescriptorRef</span> <span class="n">descriptor</span> <span class="o">=</span>
  <span class="n">CTFontDescriptorCreateWithAttributes</span><span class="p">((</span><span class="n">CFDictionaryRef</span><span class="p">)</span><span class="n">attributes</span><span class="p">);</span>
<span class="n">CTFontRef</span> <span class="n">font</span> <span class="o">=</span> <span class="n">CTFontCreateWithFontDescriptor</span><span class="p">(</span><span class="n">descriptor</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">CFRelease</span><span class="p">(</span><span class="n">descriptor</span><span class="p">);</span>
</pre></div>
<!-- FIXME: broken syntax highlighting with asterisks ** -->
<p>See you next week!</p>
<blockquote class="pull-quote">
P.S. &#8211; If you actually want to see me in person next week, I&#8217;ll be giving a half day workshop on Core Animation as well as a
shorter talk about drawing with Quartz in UIKit at the <a class="reference external" href="http://iphonedevcon.com/">iPhone/iPad DevCon in San Diego</a>.  Hopefully I&#8217;ll see you
there!</blockquote>
<br /></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/09/20/ipad-and-ios-4-custom-font-loading/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom Fonts on the iPad and iOS 4</title>
		<link>http://www.freetimestudios.com/2010/09/13/custom-fonts-on-the-ipad-and-ios-4/</link>
		<comments>http://www.freetimestudios.com/2010/09/13/custom-fonts-on-the-ipad-and-ios-4/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 06:59:16 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[Core Text]]></category>
		<category><![CDATA[idevblogaday]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=947</guid>
		<description><![CDATA[In the old days (you know, before the iPad and iOS 4), text layout in iOS was not for the faint of heart. A developer who wanted more than UILabel could provide was forced to manually layout and draw text with Quartz. Those days are gone now thanks to Core Text and it sibling CATextLayer. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F09%2F13%2Fcustom-fonts-on-the-ipad-and-ios-4%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F09%2F13%2Fcustom-fonts-on-the-ipad-and-ios-4%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><div class="document">
<p>In the old days (you know, before the iPad and iOS 4), text layout in iOS was not for the faint of heart. A developer who wanted more than
<tt class="docutils literal">UILabel</tt> could provide was forced to manually layout and draw text with Quartz. Those days are gone now thanks to Core Text and it
sibling <tt class="docutils literal">CATextLayer</tt>.</p>
<p>Core Text could fill an entire book on its own. Luckily, most of Core Text is only necessary for about 5% of iOS apps. Most of us do not
need to layout large amounts of text with complex style attributes. Sometimes we just want to use our own custom font or italicize one word
in a label. There is a solution for the rest of us: <tt class="docutils literal">CATextLayer</tt>. Like its counterparts in the Core Animation framework, <tt class="docutils literal">CATextLayer</tt>
allows us to take advantage of a complex API (Core Text in this case) without much effort.</p>
<p>We will cover a simple use of <tt class="docutils literal">CATextLayer</tt> this time: displaying a custom font. As always, I have added more code to my <a class="reference external" href="http://github.com/neror/CA360">CA360 project</a>.
Check it out on <a class="reference external" href="http://github.com/neror/CA360/blob/master/Classes/Samples/TextLayers.m">github</a> to follow along.</p>
<div class="section" id="displaying-custom-fonts">
<h2>Displaying Custom Fonts</h2>
<p>Using <tt class="docutils literal">CATextLayer</tt> to display a custom font is fairly simple. There are two things we must do to make it work:</p>
<ul class="simple">
<li>Load the font into memory (most likely from our app bundle).</li>
<li>Hand the font to our <tt class="docutils literal">CATextLayer</tt> for drawing.</li>
</ul>
<p>Once the font has been passed to our <tt class="docutils literal">CATextLayer</tt> instance, we can set the <tt class="docutils literal">string</tt> of the layer and treat it like any other Core
Animation layer. Let&#8217;s see how this looks in code.</p>
</div>
<div class="section" id="load-the-font-into-memory">
<h2>Load the Font into Memory</h2>
<p>Because <tt class="docutils literal">CATextLayer</tt> uses Core Text internally, we&#8217;ll need to touch a little of Core Text to render our custom font. Like Quartz, Core
Text is a Core Foundation API, and it is entirely C based. If you&#8217;ve done any custom drawing with Quartz, the Core Text API will look
familiar. If this is your first foray into a Core Foundation framework, don&#8217;t worry, <tt class="docutils literal">CATextLayer</tt> abstracts most of Core Text away. You
still might want to take a look at the <a class="reference external" href="http://developer.apple.com/legacy/mac/library/#referencelibrary/GettingStarted/GS_CoreFoundation/index.html">Apple Core Foundation docs</a> if this part is way over your head.</p>
<p><tt class="docutils literal">CATextLayer</tt> expects a <tt class="docutils literal">CTFontRef</tt> (CT is the prefix for all Core Text types and functions) for its <tt class="docutils literal">font</tt> attribute. This is where
we have to use Core Text directly.</p>
<p>We actually go about this in a bit of a roundabout way. Core Text does not know how to load a font from a font file. That&#8217;s the domain of
Qaurtz.  So we have to load the font file with Quartz and convert the <tt class="docutils literal">CGFontRef</tt> to a <tt class="docutils literal">CTFontRef</tt>. Thankfully, this conversion is just
a single function call.</p>
<div class="highlight"><pre><span class="o">-</span> <span class="p">(</span><span class="n">CTFontRef</span><span class="p">)</span><span class="nl">newCustomFontWithName:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="n">fontName</span>
                            <span class="nl">ofType:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="n">type</span>
                        <span class="nl">attributes:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="n">attributes</span>
<span class="p">{</span>
  <span class="n">NSString</span> <span class="o">*</span><span class="n">fontPath</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSBundle</span> <span class="n">mainBundle</span><span class="p">]</span> <span class="nl">pathForResource:</span><span class="n">fontName</span> <span class="nl">ofType:</span><span class="n">type</span><span class="p">];</span>

  <span class="n">NSData</span> <span class="o">*</span><span class="n">data</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSData</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithContentsOfFile:</span><span class="n">fontPath</span><span class="p">];</span>
  <span class="n">CGDataProviderRef</span> <span class="n">fontProvider</span> <span class="o">=</span> <span class="n">CGDataProviderCreateWithCFData</span><span class="p">((</span><span class="n">CFDataRef</span><span class="p">)</span><span class="n">data</span><span class="p">);</span>
  <span class="p">[</span><span class="n">data</span> <span class="n">release</span><span class="p">];</span>

  <span class="n">CGFontRef</span> <span class="n">cgFont</span> <span class="o">=</span> <span class="n">CGFontCreateWithDataProvider</span><span class="p">(</span><span class="n">fontProvider</span><span class="p">);</span>
  <span class="n">CGDataProviderRelease</span><span class="p">(</span><span class="n">fontProvider</span><span class="p">);</span>

  <span class="n">CTFontDescriptorRef</span> <span class="n">fontDescriptor</span> <span class="o">=</span> <span class="n">CTFontDescriptorCreateWithAttributes</span><span class="p">((</span><span class="n">CFDictionaryRef</span><span class="p">)</span><span class="n">attributes</span><span class="p">);</span>
  <span class="n">CTFontRef</span> <span class="n">font</span> <span class="o">=</span> <span class="n">CTFontCreateWithGraphicsFont</span><span class="p">(</span><span class="n">cgFont</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">fontDescriptor</span><span class="p">);</span>
  <span class="n">CFRelease</span><span class="p">(</span><span class="n">fontDescriptor</span><span class="p">);</span>
  <span class="n">CGFontRelease</span><span class="p">(</span><span class="n">cgFont</span><span class="p">);</span>
  <span class="k">return</span> <span class="n">font</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<!-- FIXME: broken syntax highlighting with asterisks ** -->
<p>As you can see, we use a <tt class="docutils literal">CGDataProvider</tt> to load the font from the app bundle and create a <tt class="docutils literal">CGFontRef</tt> with the data provider.</p>
<p>Next, we create at <tt class="docutils literal">CTFontDescriptorRef</tt>. <tt class="docutils literal">CTFont</tt> is very configurable, and the <tt class="docutils literal">CTFontDescriptor</tt> holds all of that configuration
information. We&#8217;ll get to it in a later post. You can ignore the <tt class="docutils literal">CTFontDescriptor</tt> for now.</p>
<p>The last thing we do in this method is create the <tt class="docutils literal">CTFontRef</tt> using our <tt class="docutils literal">CGFontRef</tt> and the <tt class="docutils literal">CTFontDescriptorRef</tt>. Now, our font is
loaded and ready to be used.</p>
</div>
<div class="section" id="configure-the-catextlayer">
<h2>Configure the CATextLayer</h2>
<p><tt class="docutils literal">CATextLayer</tt> could not be easier to configure. Like other <tt class="docutils literal">CALayer</tt> objects, the <tt class="docutils literal">CATextLayer</tt> exposes a set of attributes that we
can set to configure the look of our text. Since we loaded the font earlier, we can just set the <tt class="docutils literal">font</tt> attribute of <tt class="docutils literal">CATextLayer</tt>, and
the layer handles the rest.</p>
<div class="highlight"><pre><span class="n">normalTextLayer_</span> <span class="o">=</span> <span class="p">[[</span><span class="n">CATextLayer</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">font</span> <span class="o">=</span> <span class="n">font</span><span class="p">;</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">string</span> <span class="o">=</span> <span class="s">@&quot;This is just a plain old CATextLayer&quot;</span><span class="p">;</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">wrapped</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">foregroundColor</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIColor</span> <span class="n">purpleColor</span><span class="p">]</span> <span class="n">CGColor</span><span class="p">];</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">fontSize</span> <span class="o">=</span> <span class="mf">20.f</span><span class="p">;</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">alignmentMode</span> <span class="o">=</span> <span class="n">kCAAlignmentCenter</span><span class="p">;</span>
<span class="n">normalTextLayer_</span><span class="p">.</span><span class="n">frame</span> <span class="o">=</span> <span class="n">CGRectMake</span><span class="p">(</span><span class="mf">0.f</span><span class="p">,</span> <span class="mf">10.f</span><span class="p">,</span> <span class="mf">320.f</span><span class="p">,</span> <span class="mf">32.f</span><span class="p">);</span>
</pre></div>
<p>As you can see, there are a bunch of configuration options for <tt class="docutils literal">CATextLayer</tt>.  You can see them all in the <a class="reference external" href="http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CATextLayer_class/Introduction/Introduction.html">class reference doc</a>. Once
we&#8217;ve finished setting up our layer, we add it to the layer tree, and Core Animation will render it.  The final product looks something like
this:</p>
<img alt="http://www.freetimestudios.com/wp-content/uploads/2010/09/CATextLayer-Simple.png" class="aligncenter" src="http://www.freetimestudios.com/wp-content/uploads/2010/09/CATextLayer-Simple.png" />
</div>
<div class="section" id="now-unleash-the-designers">
<h2>Now, Unleash the Designers</h2>
<p>Thanks to the updates in iOS 4, developers are no longer stuck with the fonts built into iOS. Good typography can really elevate the look of
an app, and I encourage you to experiment with quality fonts. Let you designers run wild.  They&#8217;ll love you for it.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/09/13/custom-fonts-on-the-ipad-and-ios-4/feed/</wfw:commentRss>
		<slash:comments>1199</slash:comments>
		</item>
		<item>
		<title>Fun With Core Animation: Shutter Transition</title>
		<link>http://www.freetimestudios.com/2010/09/06/fun-with-core-animation-shutter-transition/</link>
		<comments>http://www.freetimestudios.com/2010/09/06/fun-with-core-animation-shutter-transition/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 05:38:26 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[idevblogaday]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=911</guid>
		<description><![CDATA[It&#8217;s all over the Twitter now that I forgot about my first #idevblogaday post. So, in the interest of hitting my deadline (and keeping my slot), this post will be quick. I&#8217;ll also keep the subject matter squarely in my wheelhouse: Core Animation. While preparing the material for my half-day workshop at iPhone/iPad DevCon at [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F09%2F06%2Ffun-with-core-animation-shutter-transition%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F09%2F06%2Ffun-with-core-animation-shutter-transition%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><div class="document">


<p>It&#8217;s all over the Twitter now that I forgot about my first <a class="reference external" href="http://idevblogaday.com/">#idevblogaday</a>
post.  So, in the interest of hitting my deadline (and keeping my slot), this
post will be quick.  I&#8217;ll also keep the subject matter squarely in my
wheelhouse: Core Animation.</p>
<p>While preparing the material for my half-day workshop at <a class="reference external" href="http://iphonedevcon.com/">iPhone/iPad DevCon</a>
at the end of the month, I added some more examples to my <a class="reference external" href="http://github.com/neror/CA360">stable of Core
Animation examples</a>. One of the new examples is based on an idea that has been
rattling around in my head for a while. I call it the shutter transition.
Rather than explain what I mean by &quot;shutter transition&quot;, I&#8217;ll let this quick
screencast do the talking for me:</p>
<iframe class="youtube-player" type="text/html" width="576" height="335"
src="http://www.youtube.com/embed/H8tj7KKJ8gU" frameborder="0"></iframe><p>While this is a fairly simple animation, it was a fun problem to solve. It was
so fun, in fact, that I solved it two different ways. I&#8217;ll briefly cover the
most universally applicable solution today, and we&#8217;ll revisit this code in a
later post to cover the other solution. This is going to go fast, so hold on
tight. Also, please forgive the directness. I&#8217;m on a deadline here.  <img src='http://www.freetimestudios.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The shutter animation can be broken into the following steps:</p>
<ul class="simple">
<li>Flatten the layer to be animated into a single bitmap.</li>
<li>Create multiple <tt class="docutils literal">CALayer</tt> objects of equal size to be the shutters.</li>
<li>Loop over all of the shutter layers and:<ul>
<li>Set the flattened bitmap to the contents of each shutter.</li>
<li>Line up all of the shutter layers horizontally.</li>
<li>Set the <tt class="docutils literal">contentsRect</tt> of each shutter to be offset slightly based
on its position in the list.</li>
</ul>
</li>
<li>Hide the original layer, and show the shutters.</li>
<li>Animate the shutters offscreen, alternating the direction.</li>
<li>Once the shutters are offscreen, remove all of them from their <tt class="docutils literal">superlayer</tt>.</li>
</ul>
<p>Got it? Good.</p>
<p>Let&#8217;s take a look at the code that actually does this. If you are so inclined,
all of the code for the shutter transition is on <a class="reference external" href="http://github.com/neror/CA360/blob/master/Classes/Fun%20Stuff/ShutterTransition.m">github</a>. Feel free to play
with this code and use it however you please in any project. You can also use
it to follow along with this post. For those of you following along in Xcode,
all of the code I&#8217;m about to quote is in the <tt class="docutils literal">doShutterTransition</tt> method.</p>
<p>Let&#8217;s get started.</p>
<p>First, We need to flatten our layer into a single bitmap. The
<tt class="docutils literal">renderInContext:</tt> method on <tt class="docutils literal">CALayer</tt> makes this very easy for us:</p>
<div class="highlight"><pre><span class="n">CGSize</span> <span class="n">layerSize</span> <span class="o">=</span> <span class="n">mainLayer_</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">;</span>
<span class="n">CGColorSpaceRef</span> <span class="n">colorSpace</span> <span class="o">=</span> <span class="n">CGColorSpaceCreateDeviceRGB</span><span class="p">();</span>
<span class="n">CGContextRef</span> <span class="n">context</span> <span class="o">=</span> <span class="n">CGBitmapContextCreate</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">layerSize</span><span class="p">.</span><span class="n">width</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">layerSize</span><span class="p">.</span><span class="n">height</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">layerSize</span><span class="p">.</span><span class="n">width</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span> <span class="n">colorSpace</span><span class="p">,</span> <span class="n">kCGImageAlphaPremultipliedLast</span><span class="p">);</span>

<span class="p">[</span><span class="n">mainLayer_</span> <span class="nl">renderInContext:</span><span class="n">context</span><span class="p">];</span>
<span class="n">UIImage</span> <span class="o">*</span><span class="n">layerImage</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIImage</span> <span class="nl">imageWithCGImage:</span><span class="n">CGBitmapContextCreateImage</span><span class="p">(</span><span class="n">context</span><span class="p">)];</span>
</pre></div>
<!-- FIXME: broken syntax highlighting with asterisks ** -->
<p>See? I told you it was easy.</p>
<p>You&#8217;ll notice that I create the two animations next. There is a good reason for
this. When an animation is added to a layer, the layer makes a copy of the
<tt class="docutils literal">CAAnimation</tt> object for its own purposes. Since we will be adding the
animations to layers inside of a loop, we can take advantage of this copy
behavior and only create the animations once. That way, we won&#8217;t incur the
overhead of instantiating and throwing away a new <tt class="docutils literal">CAAnimation</tt> object on
every loop iteration.</p>
<p>The animation code is very straightforward:</p>
<div class="highlight"><pre><span class="n">CABasicAnimation</span> <span class="o">*</span><span class="n">slideUp</span> <span class="o">=</span> <span class="p">[</span><span class="n">CABasicAnimation</span> <span class="nl">animationWithKeyPath:</span><span class="s">@&quot;position.y&quot;</span><span class="p">];</span>
<span class="n">slideUp</span><span class="p">.</span><span class="n">toValue</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithFloat:</span><span class="o">-</span><span class="p">(</span><span class="n">mainLayer_</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span> <span class="o">/</span> <span class="mf">2.f</span><span class="p">)];</span>
<span class="n">slideUp</span><span class="p">.</span><span class="n">duration</span> <span class="o">=</span> <span class="mf">1.f</span><span class="p">;</span>
<span class="n">slideUp</span><span class="p">.</span><span class="n">timingFunction</span> <span class="o">=</span> <span class="p">[</span><span class="n">CAMediaTimingFunction</span> <span class="nl">functionWithName:</span><span class="n">kCAMediaTimingFunctionEaseInEaseOut</span><span class="p">];</span>
<span class="n">slideUp</span><span class="p">.</span><span class="n">fillMode</span> <span class="o">=</span> <span class="n">kCAFillModeForwards</span><span class="p">;</span>

<span class="n">CABasicAnimation</span> <span class="o">*</span><span class="n">slideDown</span> <span class="o">=</span> <span class="p">[</span><span class="n">CABasicAnimation</span> <span class="nl">animationWithKeyPath:</span><span class="s">@&quot;position.y&quot;</span><span class="p">];</span>
<span class="n">slideDown</span><span class="p">.</span><span class="n">toValue</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithFloat:</span><span class="p">(</span><span class="n">mainLayer_</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span> <span class="o">/</span> <span class="mf">2.f</span><span class="p">)</span> <span class="o">+</span> <span class="p">[</span><span class="n">UIScreen</span> <span class="n">mainScreen</span><span class="p">].</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span><span class="p">];</span>
<span class="n">slideDown</span><span class="p">.</span><span class="n">duration</span> <span class="o">=</span> <span class="mf">1.f</span><span class="p">;</span>
<span class="n">slideDown</span><span class="p">.</span><span class="n">timingFunction</span> <span class="o">=</span> <span class="p">[</span><span class="n">CAMediaTimingFunction</span> <span class="nl">functionWithName:</span><span class="n">kCAMediaTimingFunctionEaseInEaseOut</span><span class="p">];</span>
<span class="n">slideDown</span><span class="p">.</span><span class="n">fillMode</span> <span class="o">=</span> <span class="n">kCAFillModeForwards</span><span class="p">;</span>
</pre></div>
<!-- FIXME: broken syntax highlighting with asterisks ** -->
<p>Now we need to remove our original layer from the hierarchy and start creating
and adding our &quot;shutters&quot;. We also wrap this whole loop in a <tt class="docutils literal">CATransaction</tt>
block so that the animations are all in sync.</p>
<p>Finally, we set a <tt class="docutils literal">completionBlock</tt> to remove our shutter layers from the
superview once they are offscreen.  Because we&#8217;re using blocks here, this will
only work in iOS 4+.  You could implement an animation delegate if you have to
target anything earlier than iOS 4. You poor, poor soul.</p>
<div class="highlight"><pre><span class="n">NSMutableArray</span> <span class="o">*</span><span class="n">bands</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSMutableArray</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithCapacity:</span><span class="n">BAND_COUNT</span><span class="p">];</span>
<span class="p">[</span><span class="n">mainLayer_</span> <span class="n">removeFromSuperlayer</span><span class="p">];</span>

<span class="p">[</span><span class="n">CATransaction</span> <span class="n">begin</span><span class="p">];</span>
<span class="p">[</span><span class="n">CATransaction</span> <span class="nl">setCompletionBlock:</span><span class="o">^</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
  <span class="p">[</span><span class="n">bands</span> <span class="nl">enumerateObjectsUsingBlock:</span><span class="o">^</span><span class="p">(</span><span class="kt">id</span> <span class="n">obj</span><span class="p">,</span> <span class="n">NSUInteger</span> <span class="n">idx</span><span class="p">,</span> <span class="kt">BOOL</span> <span class="o">*</span><span class="n">stop</span><span class="p">)</span> <span class="p">{</span>
    <span class="p">[</span><span class="n">obj</span> <span class="nl">setDelegate:</span><span class="nb">nil</span><span class="p">];</span>
    <span class="p">[</span><span class="n">obj</span> <span class="n">removeFromSuperlayer</span><span class="p">];</span>
  <span class="p">}];</span>
<span class="p">}];</span>

<span class="n">CGFloat</span> <span class="n">bandWidth</span> <span class="o">=</span> <span class="n">layerSize</span><span class="p">.</span><span class="n">width</span> <span class="o">/</span> <span class="p">(</span><span class="n">CGFloat</span><span class="p">)</span><span class="n">BAND_COUNT</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">BAND_COUNT</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">CALayer</span> <span class="o">*</span><span class="n">band</span> <span class="o">=</span> <span class="p">[[</span><span class="n">CALayer</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
  <span class="n">band</span><span class="p">.</span><span class="n">masksToBounds</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>

  <span class="n">CGFloat</span> <span class="n">xOffset</span> <span class="o">=</span> <span class="mf">1.f</span> <span class="o">/</span> <span class="p">(</span><span class="n">CGFloat</span><span class="p">)</span><span class="n">BAND_COUNT</span><span class="p">;</span>
  <span class="n">band</span><span class="p">.</span><span class="n">bounds</span> <span class="o">=</span> <span class="n">CGRectMake</span><span class="p">(</span><span class="mf">0.f</span><span class="p">,</span> <span class="mf">0.f</span><span class="p">,</span> <span class="n">bandWidth</span><span class="p">,</span> <span class="n">layerSize</span><span class="p">.</span><span class="n">height</span><span class="p">);</span>
  <span class="n">band</span><span class="p">.</span><span class="n">contents</span> <span class="o">=</span> <span class="p">(</span><span class="kt">id</span><span class="p">)[</span><span class="n">layerImage</span> <span class="n">CGImage</span><span class="p">];</span>
  <span class="n">band</span><span class="p">.</span><span class="n">contentsGravity</span> <span class="o">=</span> <span class="n">kCAGravityCenter</span><span class="p">;</span>
  <span class="n">band</span><span class="p">.</span><span class="n">contentsRect</span> <span class="o">=</span> <span class="n">CGRectMake</span><span class="p">(</span><span class="n">xOffset</span> <span class="o">*</span> <span class="n">i</span> <span class="p">,</span> <span class="mf">0.f</span><span class="p">,</span> <span class="n">xOffset</span><span class="p">,</span> <span class="mf">1.f</span><span class="p">);</span>
  <span class="n">CGPoint</span> <span class="n">bandOrigin</span> <span class="o">=</span> <span class="n">mainLayer_</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">origin</span><span class="p">;</span>
  <span class="n">bandOrigin</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">bandOrigin</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="p">(</span><span class="n">bandWidth</span> <span class="o">*</span> <span class="n">i</span><span class="p">);</span>
  <span class="p">[</span><span class="n">band</span> <span class="nl">setValue:</span><span class="p">[</span><span class="n">NSValue</span> <span class="nl">valueWithCGPoint:</span><span class="n">bandOrigin</span><span class="p">]</span> <span class="nl">forKeyPath:</span><span class="s">@&quot;frame.origin&quot;</span><span class="p">];</span>

  <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">view</span><span class="p">.</span><span class="n">layer</span> <span class="nl">addSublayer:</span><span class="n">band</span><span class="p">];</span>

  <span class="p">[</span><span class="n">band</span> <span class="nl">addAnimation:</span><span class="p">(</span><span class="n">i</span> <span class="o">%</span> <span class="mi">2</span><span class="p">)</span> <span class="o">?</span> <span class="n">slideUp</span> <span class="o">:</span> <span class="n">slideDown</span> <span class="nl">forKey:</span><span class="nb">nil</span><span class="p">];</span>
  <span class="p">[</span><span class="n">bands</span> <span class="nl">addObject:</span><span class="n">band</span><span class="p">];</span>
  <span class="p">[</span><span class="n">band</span> <span class="n">release</span><span class="p">];</span>
<span class="p">}</span>
<span class="p">[</span><span class="n">CATransaction</span> <span class="n">commit</span><span class="p">];</span>
<span class="p">[</span><span class="n">bands</span> <span class="n">release</span><span class="p">];</span>
</pre></div>
<!-- FIXME: broken syntax highlighting with asterisks ** -->
<p>That&#8217;s all there is to it. The real key here is the <tt class="docutils literal">contentsRect</tt> attribute
of <tt class="docutils literal">CALayer</tt>. This example was actually created to illustrate its usage
(among other things). <tt class="docutils literal">contentsRect</tt> defines what portion to show of the
image in the layer&#8217;s <tt class="docutils literal">contents</tt> attribute. You&#8217;ll notice that the elements of
the <tt class="docutils literal">contentsRect</tt> are normalized meaning that each element is in the range
<tt class="docutils literal">0 - 1</tt>. Think of the origin and size of the <tt class="docutils literal">contentsRect</tt> as percentages.</p>
<p>I know we blew through that example really quickly. I&#8217;ll be more gentle next
time. For now, I need to get this published to meet <a class="reference external" href="http://twitter.com/mysterycoconut">&#64;mysterycoconut</a>&#8216;s
deadline. <img src='http://www.freetimestudios.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Until next week&#8230;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/09/06/fun-with-core-animation-shutter-transition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SlapHappy!™ is Officially Released!</title>
		<link>http://www.freetimestudios.com/2010/02/16/slaphappy%e2%84%a2-is-officially-released/</link>
		<comments>http://www.freetimestudios.com/2010/02/16/slaphappy%e2%84%a2-is-officially-released/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 05:54:46 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=361</guid>
		<description><![CDATA[It&#8217;s February 16th on the East Coast, and SlapHappy!&#8482; is now live in the US app store. I don&#8217;t know about other countries, yet, but I assume that if it is February 16th somewhere in your country, you can get it now. To celebrate the launch, SlapHappy!&#8482; is on sale for $.99 for a limited [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F02%2F16%2Fslaphappy%25e2%2584%25a2-is-officially-released%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F02%2F16%2Fslaphappy%25e2%2584%25a2-is-officially-released%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><p>It&#8217;s February 16th on the East Coast, and SlapHappy!&trade; is now live in the US app store. I don&#8217;t know about other countries, yet, but I assume that if it is February 16th somewhere in your country, you can get it now.</p>

<p>To celebrate the launch, SlapHappy!&trade; is on sale for $.99 for a limited time. Check out the trailer below and get it in the <a href="http://slaphappygame.com/itunes">App Store</a>!</p>

<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/tgMtlvWRoqc&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/tgMtlvWRoqc&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>

<p><a href="http://slaphappygame.com/itunes"><img src="http://www.freetimestudios.com/wp-content/uploads/man/AvailableOnTheAppStore.png"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/02/16/slaphappy%e2%84%a2-is-officially-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Chat With Free Time Studios Founder, Nathan Eror, Today at 12PM CST!</title>
		<link>http://www.freetimestudios.com/2010/01/26/chat-with-free-time-studios-founder-nathan-eror-today-at-12pm-cst/</link>
		<comments>http://www.freetimestudios.com/2010/01/26/chat-with-free-time-studios-founder-nathan-eror-today-at-12pm-cst/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 16:11:23 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=303</guid>
		<description><![CDATA[Nathan will be the subject of the first 360&#124;idev speaker chat at 12PM CST today. This is a great opportunity to get a feel for his sessions at both 360&#124;idev in San Jose this April and at iPhoneDevCamp Houston this Saturday. Drop on in and ask away!]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F01%2F26%2Fchat-with-free-time-studios-founder-nathan-eror-today-at-12pm-cst%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F01%2F26%2Fchat-with-free-time-studios-founder-nathan-eror-today-at-12pm-cst%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><p>Nathan will be the subject of the first 360|idev speaker chat at 12PM CST today. This is a great opportunity to get a feel for his sessions at both <a href="http://360idev-nathane.eventbrite.com/">360|idev in San Jose this April</a> and at <a href="http://www.iphonedevcamphouston.com/">iPhoneDevCamp Houston</a> this Saturday. <a href="https://admin.na3.acrobat.com/_a204547676/nathaneror360idevsj/?refresh-parent=true">Drop on in</a> and ask away!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/01/26/chat-with-free-time-studios-founder-nathan-eror-today-at-12pm-cst/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhoneDevCamp Houston Presented by Free Time Studios</title>
		<link>http://www.freetimestudios.com/2010/01/12/iphonedevcamp-houston-presented-by-free-time-studios/</link>
		<comments>http://www.freetimestudios.com/2010/01/12/iphonedevcamp-houston-presented-by-free-time-studios/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 17:00:35 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=288</guid>
		<description><![CDATA[2010 is shaping up to be an exciting year for those of us in the iPhone and mobile software business, and there is no better way to kick it off than with a free community event. Free Time Studios is proud to be a major sponsor and primary organizer of the first ever iPhoneDevCamp Houston. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F01%2F12%2Fiphonedevcamp-houston-presented-by-free-time-studios%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F01%2F12%2Fiphonedevcamp-houston-presented-by-free-time-studios%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><p>2010 is shaping up to be an exciting year for those of us in the iPhone and mobile software business, and there is no better way to kick it off than with a free community event. Free Time Studios is proud to be a major sponsor and primary organizer of the first ever <a href="http://www.iphonedevcamphouston.com/" title="iPhoneDevCamp Houston">iPhoneDevCamp Houston</a>. If you are in the general vicinity of Houston on the last weekend of January, this is a can&#8217;t miss event. There will be presentations for people of all skill levels covering app development and marketing. Whether you are a seasoned or hopeful iPhone developer, there will be something for you at iPhoneDevCamp Houston.</p>

<p>Also, make sure to get your sleep on Friday night because we will be hacking all night Saturday. Show up with your ideas and your laptop, and work with the top iPhone development talent in the Houston area. Caffeine and sustenance will be provided.</p>

<p>Join the all of people who have already registered and <a href="http://www.iphonedevcamphouston.com/register/" title="iPhoneDevCamp Houston   &raquo; Registration">sign up here</a>. It&#8217;s free.</p>

<p>Check out the <a href="http://www.iphonedevcamphouston.com/" title="iPhoneDevCamp Houston">iPhoneDevCamp Houston website</a> for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/01/12/iphonedevcamp-houston-presented-by-free-time-studios/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introducing FTUtils: Open Source Utilities for iPhone Developers</title>
		<link>http://www.freetimestudios.com/2010/01/05/introducing-ftutils-open-source-utilities-for-iphone-developers/</link>
		<comments>http://www.freetimestudios.com/2010/01/05/introducing-ftutils-open-source-utilities-for-iphone-developers/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 19:33:13 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=252</guid>
		<description><![CDATA[For my Core Animation presentation at 360idev last year, I created a bunch of sample code to show how simple and powerful Core Animation is. I also promised that I would update the sample code with even more advanced examples. That has not really happened (yet!), and it is time for me to atone. I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F01%2F05%2Fintroducing-ftutils-open-source-utilities-for-iphone-developers%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2010%2F01%2F05%2Fintroducing-ftutils-open-source-utilities-for-iphone-developers%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><p>For my <a href="http://www.freetimestudios.com/2009/10/02/core-animation-hands-on-360idev-yes-there-is-more/" title="Core Animation: Hands-On @ 360idev. Yes, There is More! | Free Time Studios">Core Animation presentation</a> at <a href="http://www.360idev.com/" title="360|iDev the Premiere iPhone developer conference in the world!">360idev</a> last year, I created a bunch of <a href="http://github.com/neror/CA360" title="neror's CA360 at master - GitHub">sample code</a> to show how simple and powerful Core Animation is. I also promised that I would update the sample code with even more advanced examples. That has not really happened (yet!), and it is time for me to atone.</p>

<p>I am very excited to officially release a collection of utility code that I have accumulated over the past year: <a href="http://ftutils.com/" title="FTUtils - Open Source Tools for iPhone Developers"><strong>FTUtils</strong></a>! It is the first dependency I add to all of my projects, and I have already received enthusiastic feedback from developers who have stumbled on the <a href="http://github.com/neror/ftutils" title="neror's ftutils at master - GitHub">github project</a>.</p>

<p>It probably comes as no surprise that the bulk of <strong>FTUtils</strong> contains enhancements and extensions to the Core Animation API (called FTAnimation). I use Core Animation a lot, and I have tried to find elegant ways to round off some of the sharper edges of the API. <strong>FTUtils</strong> is not only about Core Animation, though. It features:</p>

<ul>
<li>A category on <code>UIView</code> that puts 13+ canned animations only a method call away.</li>
<li>Access to the <code>CAAnimation</code> objects for the canned animations so you can mix and match them all you want.</li>
<li>Implementation of the target/action pattern for animation delegate callbacks. No more huge <code>animationDidStop:finished:</code> methods!</li>
<li>Simple chaining of an arbitrary number of animations.</li>
<li>Embedding of a pre or post animation delay directly in the <code>CAAnimation</code> object (useful for chaining).</li>
<li><code>performSelector*</code> methods built for calling delegates that elegantly handle non-existent selectors and allow the passing of primitives as parameters.</li>
<li>Simple methods for reversing arrays.</li>
<li>A collection of macros to make common code patterns simpler to use.</li>
</ul>

<p>Since I use <strong>FTUtils</strong> in all of my projects, it is updated regularly with bug fixes and new features. Currently, I am working hard at documenting the whole library at <a href="http://ftutils.com/" title="FTUtils">ftutils.com</a>, and I will be pushing updates to the site as I finish chunks of the docs.</p>

<p>The iPhone developer community is an active and friendly one, and it has been very good to me. I am glad to have something to give back. Also, for those of you <a href="http://360idev-nathane.eventbrite.com/" title="360|iDev San Jose - April 11-14, 2010 - Eventbrite">planning to attend 360idev this April</a> (you should go&#8230;really), I will be speaking about advanced uses of Core Animation including an explanation of how everything in FTAnimation works.</p>

<h2>One more thing&#8230;</h2>

<p>Here&#8217;s a screencast showing off the canned animations in <strong>FTUtils</strong>. The code for this app is in the <a href="http://github.com/neror/ftutils/tree/master/Examples/" title="Examples at master from neror's ftutils - GitHub">Examples directory</a> of the project.</p>

<p>Enjoy!</p>

<p><object height='385' width='480'><param name='movie' value='http://www.youtube.com/v/UMYP-qEKs9Q&#038;hl=en_US&#038;fs=1&#038;' /><param name='allowFullScreen' value='true' /><param name='allowscriptaccess' value='always' /><embed src='http://www.youtube.com/v/UMYP-qEKs9Q&#038;hl=en_US&#038;fs=1&#038;' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='385' width='480' /></object></p>

<p><a href="http://www.iphonekicks.com/kick/?url=http%3a%2f%2fwww.freetimestudios.com%2f2010%2f01%2f05%2fintroducing-ftutils-open-source-utilities-for-iphone-developers%2f"><img src="http://www.iphonekicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.freetimestudios.com%2f2010%2f01%2f05%2fintroducing-ftutils-open-source-utilities-for-iphone-developers%2f" border="0" alt="kick it on iPhoneKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2010/01/05/introducing-ftutils-open-source-utilities-for-iphone-developers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Core Data Tips for iPhone Devs Part 2: Better Error Messages</title>
		<link>http://www.freetimestudios.com/2009/11/13/core-data-tips-for-iphone-devs-part-2-better-error-messages/</link>
		<comments>http://www.freetimestudios.com/2009/11/13/core-data-tips-for-iphone-devs-part-2-better-error-messages/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 22:13:46 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Core Data Tips & Tricks]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=204</guid>
		<description><![CDATA[Continuing our series of Core Data tips and tricks, we turn to error handling. All good developers know that error handling is an essential piece of quality software. Unfortunately for Cocoa developers, error handling can be a little cumbersome and verbose on our favorite platform. This is a small price to pay to be able [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2009%2F11%2F13%2Fcore-data-tips-for-iphone-devs-part-2-better-error-messages%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2009%2F11%2F13%2Fcore-data-tips-for-iphone-devs-part-2-better-error-messages%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><div class="document">


<p>Continuing our <a class="reference external" href="http://www.freetimestudios.com/cat/core-data/cd-tips-tricks/">series of Core Data tips and tricks</a>, we turn to error handling. All good developers know that error handling is an essential piece of quality software. Unfortunately for Cocoa developers, error handling can be a little cumbersome and verbose on our favorite platform. This is a small price to pay to be able to work with such outstanding libraries and APIs, but the constant code repetition can eat away at our keyboards. Frustratingly, the errors we work so hard to catch and handle are, sometimes, not useful at first glance. This is definitely the case when saving an <tt class="docutils literal">NSManagedObjectContext</tt>.</p>
<div class="section" id="the-problem">
<h2>The Problem</h2>
<p>Early in development, the data model model changes often, and errors are inevitable. Forget to make a new attribute optional, and the code blows up while saving the context. Because I move pretty fast and change things often, this kind of stuff happens to me all the time. Core Data provides me this error message quite often:</p>
<p><tt class="docutils literal">Domain=NSCocoaErrorDomain Code=1560 UserInfo=0x14f5480 &quot;Operation could not be completed. (Cocoa error <span class="pre">1560.)&quot;</span></tt></p>
<p>For the developer inexperienced with Core Data, this is a very disheartening message. It does not give us any indication of <em>what</em> went wrong or <em>how</em> we should attempt to fix the problem.</p>
</div>
<div class="section" id="the-solution">
<h2>The Solution</h2>
<p>It turns out that, if there is more than one error, Core Data puts an array of <tt class="docutils literal">NSError</tt> objects in the <tt class="docutils literal">userInfo</tt> dictionary with the key <tt class="docutils literal">NSDetailedErrorsKey</tt>. This is not obvious, and it drove me crazy for a while until I turned to <a class="reference external" href="http://stackoverflow.com/&quot;StackOverflow&quot;">Stack Overflow</a> where someone else had already asked my question. There, someone named Charles provided <a class="reference external" href="http://stackoverflow.com/questions/1283960/iphone-core-data-unresolved-error-while-saving/1297157#1297157">this solution</a> with code to get at the &quot;real&quot; error. Overjoyed, I turned the code into a macro, and I use it exclusively to save a context during development. Here is the macro:</p>
<div class="highlight"><pre><span class="cp">#define FT_SAVE_MOC(_ft_moc) \</span>
<span class="cp">do { \</span>
<span class="cp">  NSError* _ft_save_error; \</span>
<span class="cp">  if(![_ft_moc save:&amp;_ft_save_error]) { \</span>
<span class="cp">    NSLog(@&quot;Failed to save to data store: %@&quot;, [_ft_save_error localizedDescription]); \</span>
<span class="cp">    NSArray* _ft_detailedErrors = [[_ft_save_error userInfo] objectForKey:NSDetailedErrorsKey]; \</span>
<span class="cp">    if(_ft_detailedErrors != nil &amp;&amp; [_ft_detailedErrors count] &gt; 0) { \</span>
<span class="cp">      for(NSError* _ft_detailedError in _ft_detailedErrors) { \</span>
<span class="cp">        NSLog(@&quot;DetailedError: %@&quot;, [_ft_detailedError userInfo]); \</span>
<span class="cp">      } \</span>
<span class="cp">    } \</span>
<span class="cp">    else { \</span>
<span class="cp">      NSLog(@&quot;%@&quot;, [_ft_save_error userInfo]); \</span>
<span class="cp">    } \</span>
<span class="cp">  } \</span>
<span class="cp">} while(0);</span>
</pre></div>
<p>Now, whenever I need to save the context, I can do it safely and comfortably like so:</p>
<div class="highlight"><pre><span class="n">FT_SAVE_MOC</span><span class="p">([</span><span class="n">self</span> <span class="n">managedObjectContext</span><span class="p">])</span>
</pre></div>
<p>This macro only prints the error messages, but all I want during development is error messages in the console. This code can easily be moved to a function or method to do more robust error handling in a production scenario, but that would fill an entire post on its own. <img src='http://www.freetimestudios.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2009/11/13/core-data-tips-for-iphone-devs-part-2-better-error-messages/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Core Data Tips for iPhone Devs Part 1: Command Line Shortcuts</title>
		<link>http://www.freetimestudios.com/2009/11/11/core-data-tips-for-iphone-devs-part-1-command-line-shortcuts/</link>
		<comments>http://www.freetimestudios.com/2009/11/11/core-data-tips-for-iphone-devs-part-1-command-line-shortcuts/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 19:17:31 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Core Data Tips & Tricks]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=133</guid>
		<description><![CDATA[I recently finished migrating the data management backend for all of my games to Core Data from a custom sqlite implementation. This is part of my commitment to use more Apple APIs where it makes sense, and this one made a lot of sense. While the migration took me a couple of days, the benefits [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2009%2F11%2F11%2Fcore-data-tips-for-iphone-devs-part-1-command-line-shortcuts%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2009%2F11%2F11%2Fcore-data-tips-for-iphone-devs-part-1-command-line-shortcuts%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><div class="document">


<p>I recently finished migrating the data management backend for all of my games to Core Data from a custom sqlite implementation. This is part of my commitment to use more Apple APIs where it makes sense, and this one made a lot of sense. While the migration took me a couple of days, the benefits of using Core Data have already paid back that investment in improved performance and better data design. Among other things, my domain objects are now much more granular which allows me to pull only the little bits of data that I need when I need them. Core Data makes managing the relationships between all of these little domain objects dead simple. In other words, I don&#8217;t have to write any more <tt class="docutils literal">join</tt> queries!</p>
<p>Core Data is a massive topic, and I have only begun to scratch the surface of its usefulness. Still, I have found myself doing some repetitive tasks both at the command line and in code. Like any self respecting programmer, I hate repetitive tasks, and my Makefile and header file of macros have grown as a result. Since most of the shortcuts I have come up with will probably be useful to others, I am putting them together in a series of blog posts. This is the first of those posts.</p>
<div class="section" id="the-problem">
<h2>The Problem</h2>
<p>Core Data allows you to choose from multiple backend storage methods, and, other than having to choose a type, the data store is completely transparent. The recommended store on the iPhone is sqlite, and not only is it fast, but the schema generated by Core Data is fairly readable. Being able to poke around in the sqlite file was an immeasurable help while I was learning Core Data. The biggest problem is finding the sqlite database file. Every time you build and run your app in the simulator, the application directory is renamed with a new GUID which makes it really hard to find:</p>
<div id="attachment_146" class="wp-caption aligncenter" style="width: 414px"><a href="http://www.freetimestudios.com/wp-content/uploads/2009/10/SimulatorAppWhackAMole.png"><img src="http://www.freetimestudios.com/wp-content/uploads/2009/10/SimulatorAppWhackAMole.png" alt="Can you find your app?" title="Simulator App Whack-A-Mole" width="404" height="283" class="size-full wp-image-146" /></a><p class="wp-caption-text">Can you find your app?</p></div>
</div>
<div class="section" id="the-solution">
<h2>The Solution</h2>
<p>Thankfully, OS X has the full compliment of unix command line tools. Wrap the proper commands in a Makefile, and you have some instant command line Core Data database management tools. Unix to the rescue! Here are the four make targets that I use the most:</p>
<div class="highlight"><pre><span class="nv">SQLITE_DB_FILE</span><span class="o">=</span>AppData.sqlite
<span class="nv">SIMULATOR_HOME</span><span class="o">=</span><span class="k">$(</span>HOME<span class="k">)</span>/Library/Application<span class="se">\ </span>Support/iPhone<span class="se">\ </span>Simulator

dbshell:
      find <span class="k">$(</span>SIMULATOR_HOME<span class="k">)</span> -name <span class="s2">&quot;$(SQLITE_DB_FILE)&quot;</span> -exec sqlite3 <span class="o">{}</span> <span class="s1">&#39;;&#39;</span>

killdb:
      find <span class="k">$(</span>SIMULATOR_HOME<span class="k">)</span> -name <span class="s2">&quot;$(SQLITE_DB_FILE)&quot;</span> -exec rm <span class="o">{}</span> <span class="s1">&#39;;&#39;</span>

dbschema:
      find <span class="k">$(</span>SIMULATOR_HOME<span class="k">)</span> -name <span class="s2">&quot;$(SQLITE_DB_FILE)&quot;</span> -exec sqlite3 <span class="o">{}</span> .schema <span class="s1">&#39;;&#39;</span>

dbdump:
      find <span class="k">$(</span>SIMULATOR_HOME<span class="k">)</span> -name <span class="s2">&quot;$(SQLITE_DB_FILE)&quot;</span> -exec sqlite3 <span class="o">{}</span> .dump <span class="s1">&#39;;&#39;</span>
</pre></div>
<p>The target names should make their use self explanatory, but I&#8217;ll summarize them:</p>
<dl class="docutils">
<dt><strong>dbshell</strong></dt>
<dd>Open up the sqlite command line shell with the Core Data database selected.</dd>
<dt><strong>killdb</strong></dt>
<dd>Delete the database file. This is useful if you&#8217;re making big changes to the schema and you would rather delete the whole database and start over rather than migrating the schema.</dd>
<dt><strong>dbschema</strong></dt>
<dd>Dumps the <tt class="docutils literal">CREATE</tt> statements required to recreate the schema. This is useful to see how Core Data persists your object graph.</dd>
<dt><strong>dbdump</strong></dt>
<dd>Dumps the schema as <tt class="docutils literal">CREATE</tt> statements and all of the data as <tt class="docutils literal">INSERT</tt> statements.</dd>
</dl>
<p>There is nothing magical or difficult about these, but I have found them to be very useful while developing my data model.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2009/11/11/core-data-tips-for-iphone-devs-part-1-command-line-shortcuts/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Core Animation: Hands-On @ 360idev. Yes, There is More!</title>
		<link>http://www.freetimestudios.com/2009/10/02/core-animation-hands-on-360idev-yes-there-is-more/</link>
		<comments>http://www.freetimestudios.com/2009/10/02/core-animation-hands-on-360idev-yes-there-is-more/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 22:03:14 +0000</pubDate>
		<dc:creator>Nathan Eror</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.freetimestudios.com/?p=64</guid>
		<description><![CDATA[I was surprised and excited to see the standing room only turnout for my in depth Core Animation talk at 360idev this week. I thought it would be a popular topic, but Collin really got people fired up to learn more during his introductory talk. I was able to cover quite a bit of material [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.freetimestudios.com%2F2009%2F10%2F02%2Fcore-animation-hands-on-360idev-yes-there-is-more%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.freetimestudios.com%2F2009%2F10%2F02%2Fcore-animation-hands-on-360idev-yes-there-is-more%2F&amp;source=neror&amp;style=normal&amp;service=bit.ly&amp;service_api=R_1991eb0e663e684f67b85bf3b2ecd1f8&amp;b=2" height="61" width="50" />
			</a>
		</div><p>I was surprised and excited to see the standing room only turnout for my in depth Core Animation talk at <a href="http://www.360idev.com/" title="360|iDev the Premiere iPhone developer conference in the world!">360idev</a> this week. I thought it would be a popular topic, but <a href="http://collindonnell.com/" title="Collin Donnell">Collin</a> really got people fired up to learn more during his introductory talk. I was able to cover quite a bit of material in my 80 minutes, and I got some awesome feedback from the developers in attendance. The most common thing I heard from developers was some variation of &#8220;I didn&#8217;t know I could do that!&#8221; or &#8220;You just saved me <em>X</em> lines of code!&#8221; It was simultaneously flattering and disappointing.</p>

<p><strong>SlapHappy!</strong> is written entirely with Core Animation, and I&#8217;ve dug deeper into the API than most people outside of Apple. I&#8217;d forgotten how much of the stuff I know was picked up through a combination of trial and error, debugging, digging into headers, and re-reading <a href="http://pragprog.com/titles/bdcora/core-animation-for-mac-os-x-and-the-iphone" title="The Pragmatic Bookshelf | Core Animation for Mac OS X and the iPhone">books</a> and documentation. I didn&#8217;t expect that others have been as intimate with Core Animation as I have, but I was still a little surprised to see the lights go on in people&#8217;s heads as I spoke.</p>

<p>My experience presenting at 360idev proved what I had suspected: Many iPhone developers look at Core Animation as a low level framework hidden inside the black box of UIKit. I&#8217;d like to change that perception. While you can write an entire iPhone app without even knowing that Core Animation exists, just a basic understanding and application of the API and its concepts can go a long way to separate your app from the other 85,000+ in the app store.</p>

<p>Since I was not able to cover everything I wanted to in my 80 minutes at 360idev, I am putting together a <a href="http://www.freetimestudios.com/cat/core-animation/" title="Core Animation | Free Time Studios">series of blog posts</a> with Core Animation tips, tricks, lessons learned, and code. Consider this the first in the series. I&#8217;ll kick it off with my slide deck and a link to the more than 1,400 lines of sample code I prepared for the presentation.</p>

<ul>
<li><strong>The Slide Deck:</strong> <a href="http://www.freetimestudios.com/wp-content/uploads/2009/10/NathanEror_CoreAnimation_360idev.pdf" title="">Core Animation Hands-On: Building Complex and Attractive Cocoa Touch Interfaces</a></li>
<li><strong>The Code:</strong> <a href="http://github.com/neror/CA360" title="neror's CA360 at master - GitHub">http://github.com/neror/CA360</a></li>
</ul>

<p>I will be adding to the sample code project as I work on this series so make sure to <a href="http://github.com/neror/CA360/toggle_watch">watch</a> the project on github. Also, if you have any burning Core Animation questions that you&#8217;d like to see covered in this series, drop me an email or add a comment to this post.</p>

<p>Oh, and thank you again <a href="http://lordbron.wordpress.com/" title="Tom&#8217;s Blog">Tom</a> and <a href="http://johnwilker.com/" title="Community, Code, Awesomeness">John</a> for giving me the opportunity to be a part of such a tremendous show!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freetimestudios.com/2009/10/02/core-animation-hands-on-360idev-yes-there-is-more/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using xcache (Feed is rejected)
Page Caching using xcache
Database Caching 2/17 queries in 0.008 seconds using xcache
Object Caching 2949/2982 objects using xcache

Served from: www.freetimestudios.com @ 2012-02-04 21:02:29 -->
