<?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>voyce &#187; Mac</title>
	<atom:link href="http://www.voyce.com/index.php/category/software-development/mac/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.voyce.com</link>
	<description>Programming and debugging tidbits</description>
	<lastBuildDate>Sun, 15 Jan 2012 13:10:46 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Drawing animated shapes and text in Core Animation layers</title>
		<link>http://www.voyce.com/index.php/2011/12/03/drawing-animated-shapes-and-text-in-core-animation-layers/</link>
		<comments>http://www.voyce.com/index.php/2011/12/03/drawing-animated-shapes-and-text-in-core-animation-layers/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 12:30:01 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CALayer]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[Core Graphics]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=1370</guid>
		<description><![CDATA[Using paths and text to simple create composite animated graphics with Core Graphics, UIKit and Core Animation.]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_1399" class="wp-caption alignleft" style="width: 148px"><a href="http://www.voyce.com/wp-content/uploads/2011/12/star_hello.png"><img src="http://www.voyce.com/wp-content/uploads/2011/12/star_hello.png" alt="Star and text" title="star_hello" width="138" height="149" class="size-full wp-image-1399" /></a><p class="wp-caption-text">Star and text</p></div>The other day I was overcome by the desire to create an animated start-burst, price-tag type graphic with iOS. Time to break out some Core Graphics and Core Animation code. On the way to getting it going, I came across some interesting gotchas, which I thought it&#8217;d be useful to talk about here.<br />
<span id="more-1370"></span></p>
<h3>Drawing the basic shape</h3>
<p>The first step is to draw the &#8217;star&#8217; shape. I decided to create a re-usable path, although at the minute I&#8217;m actually only drawing it once, so the benefits are limited. Doing this involves using the <code>CGPath...</code> versions of the Core Graphics functions, that add themselves to a mutable path objects, rather than being drawn directly on the currently active graphics context.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">    CGMutablePathRef r <span style="color: #002200;">=</span> CGPathCreateMutable<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #11740a; font-style: italic;">// Always have to move to a start point</span>
    CGPathMoveToPoint<span style="color: #002200;">&#40;</span>r, <span style="color: #a61390;">NULL</span>, x1, y1<span style="color: #002200;">&#41;</span>; 
    CGPathAddLineToPoint<span style="color: #002200;">&#40;</span>r, <span style="color: #a61390;">NULL</span>, x2, y2<span style="color: #002200;">&#41;</span>;
    CGPathCloseSubpath<span style="color: #002200;">&#40;</span>r<span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Once you&#8217;ve got created the path you can merrily set various stroke and fill colours and draw it over-and-over to your hearts content.</p>
<p><a href="http://www.voyce.com/wp-content/uploads/2011/12/star_algo.png"><img src="http://www.voyce.com/wp-content/uploads/2011/12/star_algo.png" alt="star_algo" title="star_algo" width="145" height="160" class="alignleft size-full wp-image-1383" /></a>The star drawing is parameterised in a few ways: we can set the inner radius (r2), outer radius (r1) and the number of points, which must be divisible by 3. We draw the points in groups of three, the first on the outer radius, then the inner, then the last on the outer. In that way the sections tesselate into a complete circle.</p>
<h3>Using it with CALayer</h3>
<p>So now we&#8217;ve got some code to draw the shape we want, we need a way to get it onto the screen, using <code>CALayer</code>s. There are 3 main ways of providing content for layers:</p>
<ul>
<li>Use a delegate that implements <code>drawInContext</code> (and don&#8217;t forget to call <code>setNeedsDisplay</code> at least once to cause it be drawn!)</li>
<li>Set the content to a <code>CGImageRef</code>. Meh&#8230; that&#8217;s going to mean it&#8217;s a bitmap, with all the associated aliasing/scaling issues.</li>
<li>Subclassing. Nah.</li>
</ul>
<p>We&#8217;ll use the first approach; we can create a simple <code>NSObject</code>-derived class that can manage the layer hierarchy (more of that later) and implement the required selector on it. In that function we can switch on the layer we&#8217;re being asked to draw, and do the appropriate handling:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawLayer<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CALayer <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theLayer
        inContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGContextRef<span style="color: #002200;">&#41;</span>context 
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>theLayer <span style="color: #002200;">==</span> _textLayer<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// ...</span>
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>theLayer <span style="color: #002200;">==</span> _starLayer<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// ...</span>
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<h3>Animating</h3>
<p>We&#8217;re only going to be doing fairly basic rotation animation here, so we can use <code>CABasicAnimation</code>. We use the key-value coding support to specify the <code>transform.rotation</code> property as the target. This is an alias for rotation around the Z axis, which is pointing &#8220;out&#8221; of the screen. We rotate from 0 to 2*pi radians, repeating essentially indefinitely by specifying a large repeatCount.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">    CABasicAnimation <span style="color: #002200;">*</span>animation <span style="color: #002200;">=</span> 
        <span style="color: #002200;">&#91;</span>CABasicAnimation animationWithKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;transform.rotation&quot;</span><span style="color: #002200;">&#93;</span>;
    animation.duration<span style="color: #002200;">=</span><span style="color: #2400d9;">8.0</span>;
    animation.repeatCount<span style="color: #002200;">=</span>HUGE_VALF;
    animation.autoreverses<span style="color: #002200;">=</span><span style="color: #a61390;">NO</span>;
    animation.fromValue<span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#93;</span>;
    animation.toValue<span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span>TWOPI<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>_starLayer addAnimation<span style="color: #002200;">:</span>animation forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;rotation&quot;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<h3>Drawing the text</h3>
<p>This was an interesting one. I originally started looking at a <code>CATextLayer</code>-based solution, but was surprised to find that it&#8217;s quite difficult to get vertical alignment within a rectangle. Instead, I decided to use the <code>NSString</code> UIKit additions that provide enough drawing and &#8211; importantly &#8211; measuring functions for us to work out exactly where we need to place the text.    </p>
<p>One important thing to note here is that we&#8217;re potentially mixing Core Graphics and UIKit functions here. They have different expectations about how to get hold of the required graphics context; with Core Graphics it&#8217;s always passed explicitly, whereas UIKit will grab the current context. This means that if you try and call <code>drawInRect</code> within your <code>drawLayer</code> function, you&#8217;ll see errors like &#8220;Invalid context: 0&#215;0&#8243; on the console, and no output.</p>
<p>The solution is simple when you know how: tell UIKit about your explicit context, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawLayer<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CALayer <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theLayer
        inContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGContextRef<span style="color: #002200;">&#41;</span>context 
<span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// ...</span>
    <span style="color: #11740a; font-style: italic;">// Let UIKit know about this context</span>
    UIGraphicsPushContext<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;
    <span style="color: #11740a; font-style: italic;">// Because this function uses it internally...</span>
    <span style="color: #002200;">&#91;</span>myString drawInRect<span style="color: #002200;">:</span>r 
                     withFont<span style="color: #002200;">:</span>font
            lineBreakMode<span style="color: #002200;">:</span>UILineBreakModeClip 
                    alignment<span style="color: #002200;">:</span>UITextAlignmentCenter<span style="color: #002200;">&#93;</span>;
    UIGraphicsPopContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>By measuring the text before we draw, we can align it centrally vertically and fill the space horizontally, letting iOS worry about the horizontal alignment. <code>sizeWithFont</code> takes into account a bounding rectangle and our desired breaking/clipping options:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">        CGSize sz <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>s sizeWithFont<span style="color: #002200;">:</span>font 
                 constrainedToSize<span style="color: #002200;">:</span>theLayer.bounds.size 
                     lineBreakMode<span style="color: #002200;">:</span>UILineBreakModeClip<span style="color: #002200;">&#93;</span>;</pre></div></div>

<h3>Setting up a layer hierarchy</h3>
<p>Given that I wanted some parts of the thing to rotate, and others to be static, I needed to create multiple layers and put them together. This is very easily achieved by adding layers to the <code>subLayers</code> collection of our root layer, then we return the root layer and add that to the view.</p>
<p><div id="attachment_1391" class="wp-caption alignright" style="width: 170px"><a href="http://www.voyce.com/wp-content/uploads/2011/12/star_layers1.png"><img src="http://www.voyce.com/wp-content/uploads/2011/12/star_layers1.png" alt="Layer arrangement" title="star_layers" width="160" height="194" class="size-full wp-image-1391" /></a><p class="wp-caption-text">Layer arrangement</p></div>The layer set-up looks like this, with the root being empty, and having first the star layer, then the text layer added to the sublayers. This is just because <code>addSublayer</code> appends the sublayer, instead we could use the <code>insertSublayer</code> overloads to be explicit about the ordering we desire.<br />
<br clear="all"/><br />
The set-up function returns the root layer, and then we add that to our view:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">    _star <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>StarLayer alloc<span style="color: #002200;">&#93;</span> initWithRect<span style="color: #002200;">:</span>CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">100</span>, <span style="color: #2400d9;">100</span>, <span style="color: #2400d9;">100</span>, <span style="color: #2400d9;">100</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self.view.layer<span style="color: #002200;">&#93;</span> addSublayer<span style="color: #002200;">:</span>_star.root<span style="color: #002200;">&#93;</span>;</pre></div></div>

<h3>Next Steps</h3>
<p>Here&#8217;s a red star and random text sitting a bit incongruously in a prototype of a spelling app I&#8217;m writing. </p>
<p><iframe width="200" height="165" src="http://www.youtube.com/embed/kAgYThdoy_c?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p>It would be good to create a whole load of stars (probably not with text in) and shoot them across the screen in a star-burst by generating a random direction/speed vector and animating their speeds, opacity and scale to make them fade out.</p>
<p>You can check out the code <a href="https://github.com/voyce/StarLayer">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2011/12/03/drawing-animated-shapes-and-text-in-core-animation-layers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating an iPad flip-clock with Core Animation</title>
		<link>http://www.voyce.com/index.php/2010/04/10/creating-an-ipad-flip-clock-with-core-animation/</link>
		<comments>http://www.voyce.com/index.php/2010/04/10/creating-an-ipad-flip-clock-with-core-animation/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 17:48:04 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[iPad]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=791</guid>
		<description><![CDATA[Using Core Animation to create flip-card number animations on the iPad and iPhone]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.voyce.com/wp-content/uploads/2010/04/flipclock_one.png"><img src="http://www.voyce.com/wp-content/uploads/2010/04/flipclock_one.png" alt="flipclock_one" title="flipclock_one" width="69" height="127" class="alignleft size-full wp-image-793" /></a>As part of the sliding puzzle game I&#8217;m developing for the iPhone and iPad (well, I can&#8217;t survive on the profits from <a href="http://voyce.com/BattleFingers/">BattleFingers</a> forever), I looked for a way to represent a numeric score and time display in an interesting way. One of the nicer visual effects you could use for this is the &#8220;flip-card clock&#8221; style, where each number consists of a top and bottom part, and the top part flips down to reveal the next number. It&#8217;s been used in a few other places including the home screen in the HTC Diamond device, and its physical, realistic style fits well with the iPad, so I set about creating a version for the iPhone and iPad using the built-in Core Animation library. Read on for more details.<br />
<span id="more-791"></span><br />
I started by thinking about the motions that would be required for the animation. We can break it down as three elements, the top, the bottom and the flipping part. Each of these parts can be represented as a Core Animation Layer (a <code>CALayer</code>). We create them using the class method on CALayer, there&#8217;s no additional <code>retain</code> here, as the <code>_toplayer</code> property is retained.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">_toplayer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CALayer layer<span style="color: #002200;">&#93;</span>;</pre></div></div>

<h2>Splitting images</h2>
<p>Now we&#8217;ve got the layers, we need something to but into them. I didn&#8217;t want to create lots of pre-processed images for the top and bottom sections of each number, so instead I wrote a routine to split the images in code, drawing each half into an image context and grabbing a <code>UIImage</code> from it. This is then stored in an array for later use. We can get any of the elements from the array and set it as the <code>content</code> of the layer as required.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// The size of each part is half the height of the whole image</span>
CGSize size <span style="color: #002200;">=</span> CGSizeMake<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>img size<span style="color: #002200;">&#93;</span>.width, <span style="color: #002200;">&#91;</span>img size<span style="color: #002200;">&#93;</span>.height<span style="color: #002200;">/</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Create image-based graphics context for top half</span>
UIGraphicsBeginImageContext<span style="color: #002200;">&#40;</span>size<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Draw into context, bottom half is cropped off</span>
<span style="color: #002200;">&#91;</span>img drawAtPoint<span style="color: #002200;">:</span>CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.0</span>,<span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">// Grab the current contents of the context as a UIImage </span>
<span style="color: #11740a; font-style: italic;">// and add it to our array</span>
UIImage <span style="color: #002200;">*</span>top <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIGraphicsGetImageFromCurrentImageContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> retain<span style="color: #002200;">&#93;</span>;			
<span style="color: #002200;">&#91;</span>_imagesTop addObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>top<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Now draw the image starting half way down, to get the bottom half</span>
<span style="color: #002200;">&#91;</span>img drawAtPoint<span style="color: #002200;">:</span>CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.0</span>,<span style="color: #002200;">-</span><span style="color: #002200;">&#91;</span>img size<span style="color: #002200;">&#93;</span>.height<span style="color: #002200;">/</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">// And store that image in the array too</span>
UIImage <span style="color: #002200;">*</span>bottom <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIGraphicsGetImageFromCurrentImageContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> retain<span style="color: #002200;">&#93;</span>;			
<span style="color: #002200;">&#91;</span>_imagesBottom addObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>bottom<span style="color: #002200;">&#93;</span>;
&nbsp;
UIGraphicsEndImageContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Now our <code>_imagesTop</code> and <code>_imagesBottom</code> arrays contains all the images we need, let&#8217;s get &#8216;em moving.</p>
<h2>Applying animation</h2>
<p><div id="attachment_808" class="wp-caption alignright" style="width: 212px"><a href="http://www.voyce.com/wp-content/uploads/2010/04/flipclock_axes1.png"><img src="http://www.voyce.com/wp-content/uploads/2010/04/flipclock_axes1-202x300.png" alt="The axes and anchor point of a CALayer" title="flipclock_axes" width="202" height="300" class="size-medium wp-image-808" /></a><p class="wp-caption-text">The axes and anchor point of a CALayer</p></div>The animation we need to apply to the &#8216;flipping&#8217; part is a rotation around the bottom of the layer, at the join between the two halves. The default location of the anchor point is the middle of the layer, which would mean the piece would rotate around the middle, but we can easily change it to instead be at the middle in the bottom (for our purposes it could be anywhere on the bottom, as we&#8217;re only interested in x-axis rotation):</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">_fliplayer.anchorPoint <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.5</span>, <span style="color: #2400d9;">1.0</span><span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>I use the <code>CATransform3DMakeRotation</code> function to create a transform around the X axis using the vector [1,0,0]. For the first part of the motion, we go from 0 radians to pi/2 radians (0 to 90 degrees), using an explicit <code>CABasicAnimation</code> object:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CABasicAnimation <span style="color: #002200;">*</span>topAnim <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CABasicAnimation animationWithKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;transform&quot;</span><span style="color: #002200;">&#93;</span>;
topAnim.duration<span style="color: #002200;">=</span><span style="color: #2400d9;">0.25</span>;
topAnim.repeatCount<span style="color: #002200;">=</span><span style="color: #2400d9;">1</span>;
topAnim.fromValue<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSValue</span> valueWithCATransform3D<span style="color: #002200;">:</span>CATransform3DMakeRotation<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">1</span>, <span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">float</span> f <span style="color: #002200;">=</span> <span style="color: #002200;">-</span>M_PI<span style="color: #002200;">/</span><span style="color: #2400d9;">2</span>;
topAnim.toValue<span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSValue</span> valueWithCATransform3D<span style="color: #002200;">:</span>CATransform3DMakeRotation<span style="color: #002200;">&#40;</span>f, <span style="color: #2400d9;">1</span>, <span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
topAnim.delegate <span style="color: #002200;">=</span> self;
topAnim.removedOnCompletion <span style="color: #002200;">=</span> FALSE;
<span style="color: #002200;">&#91;</span>_fliplayer addAnimation<span style="color: #002200;">:</span>topAnim forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithUTF8String<span style="color: #002200;">:</span>k_TopAnimKey<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<h2>Drawing layer content</h2>
<p>Unfortunately a CALayer doesn&#8217;t have a &#8220;back&#8221;, so creating the flip layer is not as easy as it could be. We need to add a step in the process to change the image displayed by the flip layer half way through its fall. We can do this in a variety of ways, I&#8217;ve chosen to set a delegate object to perform the drawing of the layer contents:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>_fliplayer setDelegate<span style="color: #002200;">:</span>_layerHelper<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>This means our delegate object (<code>_layerHelper</code>) has its <code>drawLayer</code> method called whenever the layer needs to display its contents. Be wary though, this may not be as often as you think! Core graphics aggressively caches the contents of the layer, and will only call your delegate when absolutely necessary. You can force it to happen by calling <code>setNeedsDisplay</code>, which invalidates the contents of the layer:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>_fliplayer setNeedsDisplay<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>I encapsulated this in the helper object itself, by providing a custom implementation of the <code>isTop</code> property setter that calls <code>setNeedsDisplay</code>. At least that way callers don&#8217;t have to be aware of this requirement.</p>
<p>The <code>drawLayer</code> method itself simply draws one of two images into the context, depending on whether it&#8217;s in &#8216;top&#8217; mode. A slight further complication is that when drawing the bottom part, the image needs to be inverted to display upside down. This is achieved by applying a translation and scale to the context before drawing the image:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGContextSaveGState<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;
CGContextTranslateCTM<span style="color: #002200;">&#40;</span>context, 0.0f, r.size.height<span style="color: #002200;">&#41;</span>;
CGContextScaleCTM<span style="color: #002200;">&#40;</span>context, 1.0f, <span style="color: #002200;">-</span>1.0f<span style="color: #002200;">&#41;</span>;
&nbsp;
CGContextDrawImage<span style="color: #002200;">&#40;</span>context, r, <span style="color: #002200;">&#91;</span>_imgTop CGImage<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
CGContextRestoreGState<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;</pre></div></div>

<h2>Avoiding implicit animation</h2>
<p>I&#8217;ve tried to avoid using implicit animation here, instead using explicit construction of <code>CABasicAnimation</code> objects, because we need some control of when things happen, and the order in which they happen. Normally, it would be easier to just set some property of the view and let the OS manage animating it. Many properties have default transition that are applied whenever they&#8217;re changed, so it takes some additional effort to make them change immediately.</p>
<p>In our example we change the contents of the top half and show the flip layer, but we need that to happen immediately so we disable actions within an explicit transaction that we then commit. This gives us the control we need, and avoids the default behaviour of the transition occurring when the message loop next runs.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>CATransaction begin<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>CATransaction setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kCFBooleanTrue
				forKey<span style="color: #002200;">:</span>kCATransactionDisableActions<span style="color: #002200;">&#93;</span>;
_toplayer.contents <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>_imagesTop objectAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self getNextIndex<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> CGImage<span style="color: #002200;">&#93;</span>;
_fliplayer.hidden <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;
<span style="color: #002200;">&#91;</span>CATransaction commit<span style="color: #002200;">&#93;</span>;</pre></div></div>

<h2>Getting some perspective</h2>
<p>Although the images I&#8217;ve used to illustrate this post are isometric, what we really want is a front-on perspective view, so that the falling piece seems to stick out. For this we have to set a <code>sublayerTransform</code> on the view&#8217;s inherent layer, by setting an individual element on a transform:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CATransform3D aTransform <span style="color: #002200;">=</span> CATransform3DIdentity;
<span style="color: #a61390;">float</span> zDistance <span style="color: #002200;">=</span> <span style="color: #2400d9;">1000</span>;
aTransform.m34 <span style="color: #002200;">=</span> <span style="color: #2400d9;">1.0</span> <span style="color: #002200;">/</span> <span style="color: #002200;">-</span>zDistance;	
<span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span>.sublayerTransform <span style="color: #002200;">=</span> aTransform;</pre></div></div>

<p>This gives us a much more realistic look.</p>
<h2>Putting it together</h2>
<p>Wow, so now we&#8217;ve got some appropriately sliced images, some layers and some animations. Let&#8217;s put them together to get the final effect.<br />
<div id="attachment_812" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.voyce.com/wp-content/uploads/2010/04/flipclock.png"><img src="http://www.voyce.com/wp-content/uploads/2010/04/flipclock-300x96.png" alt="The animation states (last is same as first)" title="flipclock" width="300" height="96" class="size-medium wp-image-812" /></a><p class="wp-caption-text">The animation states (last is same as first)</p></div><br />
I&#8217;ve used a very simple state machine that moves through 3 states; TopToMiddle, MiddleToBottom, ResetForNext. We can use the <code>animationDidStop</code> delegate as the state transition point. We don&#8217;t have to bother determining exactly which animation finished, because we do the same thing (change state) regardless.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationDidStop<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CAAnimation <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>oldAnimation finished<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>flag
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>self changeState<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<ul>
<li><strong>TopToMiddle</strong>: show flip layer, and start rotation through 90 degrees</li>
<li><strong>MiddleToBottom</strong>: change image on flip layer, start rotation through further 90 degrees</li>
<li><strong>ResetForNext</strong>: change displayed top and bottom layer contents and hide flip layer</li>
</ul>
<p>Let&#8217;s see how it looks in action:<br />
<object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/RbPmAl_AeSU&#038;hl=en_US&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/RbPmAl_AeSU&#038;hl=en_US&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2010/04/10/creating-an-ipad-flip-clock-with-core-animation/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>BattleFingers is here!</title>
		<link>http://www.voyce.com/index.php/2009/02/03/battlefingers-is-here/</link>
		<comments>http://www.voyce.com/index.php/2009/02/03/battlefingers-is-here/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 08:01:57 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[battlefingers]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=78</guid>
		<description><![CDATA[
Well, I&#8217;ve done it: I&#8217;ve got my first game live on the AppStore. It&#8217;s been an interesting journey. I&#8217;m terribly bad at getting my hands on devkits and SDKs, having a play with them and then not doing anything constructive. This dates way back to things like the Playstation NetYaroze, which was pretty expensive, and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.voyce.com/BattleFingers"><img title="BattleFingers" src="http://www.voyce.com/BattleFingers/bftext.png" alt="BattleFingers text" hspace="10" vspace="5" width="100" height="69" align="left" /></a></p>
<p>Well, I&#8217;ve done it: I&#8217;ve got my first game live on the AppStore. It&#8217;s been an interesting journey. I&#8217;m terribly bad at getting my hands on devkits and SDKs, having a play with them and then not doing anything constructive. This dates way back to things like the Playstation NetYaroze, which was pretty expensive, and with which I failed to produce anything concrete. So this time around all the pieces were in place: shiny new &#8220;gaming&#8221; kit, interesting SDK, low cost of entry. I was determined to create!</p>
<p>I&#8217;ll be making a series of posts on the process and details of creating it, in the interest of sharing the fun. In the meantime, you can find out more about the game <a title="BattleFingers page" href="http://www.voyce.com/BattleFingers">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2009/02/03/battlefingers-is-here/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sound formats for iPhone development</title>
		<link>http://www.voyce.com/index.php/2009/01/06/sound-formats-for-iphone-development/</link>
		<comments>http://www.voyce.com/index.php/2009/01/06/sound-formats-for-iphone-development/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 23:10:48 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[caf]]></category>
		<category><![CDATA[endian]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[libsndfile]]></category>
		<category><![CDATA[wav]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=58</guid>
		<description><![CDATA[Ahh, back to work today. It&#8217;s pretty tough getting back into the swing of things after what turned out to be a long break this year. While I was off I finally got to spend some time working on an iPhone game. After getting hold of the SDK a while back, it&#8217;s only now that [...]]]></description>
			<content:encoded><![CDATA[<p>Ahh, back to work today. It&#8217;s pretty tough getting back into the swing of things after what turned out to be a long break this year. While I was off I finally got to spend some time working on an iPhone game. After getting hold of the SDK a while back, it&#8217;s only now that I&#8217;ve gotten around to doing something with it.</p>
<p>One of the things that seemed a little odd about the SDK is it&#8217;s use of CAF-format audio files, detailed <a href="http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/CAF_intro/chapter_1_section_1.html">here</a>. I got hold of a few very nice audio samples from the <a href="http://www.freesound.org">freesound</a> site, but needed to convert them from WAVs to CAFs.</p>
<p>I thought ffmpeg might be up to the job, but the version I had didn&#8217;t list it as an avaliable output format using <code>ffmpeg -formats</code>. However after a bit of digging I discovered that it is supported by <a href="http://www.mega-nerd.com/libsndfile/">libsndfile</a>, so set about installing it using <a href="http://www.macports.org">MacPorts</a>:</p>
<blockquote><p><code>sudo port install libsndfile</code></p></blockquote>
<p>Then I used the included libsndfile-convert app to convert my file:</p>
<blockquote><p><code>libsndfile-convert file.wav file.caf</code></p></blockquote>
<p>The output format is inferred from the file extension, so you don&#8217;t have to specify it. However, when I rebuilt and ran my iPhone app using the new file, it didn&#8217;t play back. I suspected there may be something wrong with the format of the file, so I took a look to see what <a href="http://en.wikipedia.org/wiki/File_(Unix)">file</a> reported. For the original WAV file I got</p>
<blockquote><p><code>file.wav: RIFF <strong>(little-endian)</strong> data, WAVE audio, Microsoft PCM, 16 bit, mono 44100 Hz</code></p></blockquote>
<p>Unfortunately file doesn&#8217;t work on .CAF files, but you can open them using QuickTime Player, and using the Movie Inspector window you can see that the file has the following format:</p>
<blockquote><p><code>16-bit Integer <strong>(Big Endian)</strong>, Mono, 44.100 kHz</code></p></blockquote>
<p>So it looks like the problem may be libsndfile-convert changing the endian-ness of the file contents, from the x86-style little-endian to Motorola-ish (i.e. pre-x86 Mac) big-endian, which is a bit of a pain. According to the docs, the libsndfile API supports endian-ness manipulation, so it&#8217;s probably just the case that the helper app is doing the wrong thing automatically. I&#8217;ll look at putting together a small command line app to use the API directly and enable me to batch process .WAV files correctly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2009/01/06/sound-formats-for-iphone-development/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Back to Mac</title>
		<link>http://www.voyce.com/index.php/2007/11/03/back-to-mac/</link>
		<comments>http://www.voyce.com/index.php/2007/11/03/back-to-mac/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 22:43:36 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=21</guid>
		<description><![CDATA[Well, I’ve finally got round to getting my hands on a Mac &#8211; a shiny 17″ MacBook Pro, no less &#8211; after last being heavily involved in Mac development about a decade ago when it was all about the somewhat basic IDE (at least in today’s terms) MPW &#8211; the Macintosh Programmer’s Workshop. Check it [...]]]></description>
			<content:encoded><![CDATA[<p class="postentry">Well, I’ve finally got round to getting my hands on a Mac &#8211; a shiny 17″ MacBook Pro, no less &#8211; after last being heavily involved in Mac development about a decade ago when it was all about the somewhat basic IDE (at least in today’s terms) MPW &#8211; the <a href="http://developer.apple.com/tools/mpw-tools/">Macintosh Programmer’s Workshop</a>. Check it out if you’re doing any retro Mac OS 7 coding, and aren’t scared of an environment without intellisense! It was a blessed relief when <a href="http://en.wikipedia.org/wiki/Metrowerks">MetroWerks</a> came along with CodeWarrior and bought Mac development out of the dark ages. Gutted; I’ve just discovered that they actually discontinued it in July 2005. Still, having just run up Xcode, I can safely say it’s living on in spirit.</p>
<p>More by luck than judgment I picked up the machine a couple of days after the launch of Leopard, so got that included, and it’s a good job because one of the killer features for me was bootcamp, and this comes as standard with the new OS. Don’t worry, I won’t be going into excruciating detail about the other new features &#8211; but mostly because I haven’t used previous versions of the OS enough to be able to make a worthwhile comparison.</p>
<p>Despite that, I still think that it’s a stark reminder of how good an OS can be; a solid foundation combined with a good consistent and cutting edge UI experience.</p>
<p>But I’m off to boot back into Windows for a quick bit of <a href="http://orange.half-life2.com/hl2ep2.html">HL2 EP2</a>…</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2007/11/03/back-to-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

