<?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>Cocoa Is My Girlfriend &#187; iPod Touch</title>
	<atom:link href="http://www.cimgf.com/category/ipod-touch/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cimgf.com</link>
	<description>Taglines are for Windows programmers</description>
	<lastBuildDate>Wed, 11 Jan 2012 15:00:37 +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>Saving JSON to Core Data</title>
		<link>http://www.cimgf.com/2011/06/02/saving-json-to-core-data/</link>
		<comments>http://www.cimgf.com/2011/06/02/saving-json-to-core-data/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 15:42:16 +0000</pubDate>
		<dc:creator>Tom Harrington</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[core-data]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1424</guid>
		<description><![CDATA[Hi, I&#8217;m new here. You may know me as @atomicbird on Twitter. Just a few days ago my book Core Data for iOS: Developing Data-Driven Applications for the iPad, iPhone, and iPod touch (co-written with the excellent Tim Isted) was published, and Matt invited me to contribute some Core Data tips to CIMGF. I&#8217;m going [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, I&#8217;m new here. You may know me as <a href="http://twitter.com/#!/atomicbird">@atomicbird</a> on Twitter. Just a few days ago my book <a href="http://click.linksynergy.com/fs-bin/click?id=7x2bowiz7Uk&#038;offerid=163217.1350490&#038;type=2&#038;subid=0">Core Data for iOS: Developing Data-Driven Applications for the iPad, iPhone, and iPod touch</a> (co-written with the excellent Tim Isted) was published, and Matt invited me to contribute some Core Data tips to CIMGF. I&#8217;m going to start off discussing taking JSON data from a web service and converting it to Core Data storage. Along the way I&#8217;ll cover how to inspect managed objects to find out what attributes they have and what the attribute types are.</p>

<p>Publishing lead times being what they are, this post covers information not included in the book.
<span id="more-1424"></span></p>

<h2>The Ugly/Crude Way</h2>

<p>I&#8217;m going to assume that the incoming JSON more or less matches your managed object, i.e. that you have a JSON dictionary with keys that match the attribute names of your Core Data entities. Given a dictionary <code>jsonDict</code> that has been created by parsing incoming JSON data using a JSON library (<a href="https://github.com/TouchCode/TouchJSON">TouchJSON</a> and <a href="http://code.google.com/p/json-framework/">json-framework</a> are good choices) and a managed object imaginatively called <code>myObj</code>, the dead simple approach is to just do something like:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>myObj setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>jsonDict objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;name&quot;</span><span style="color: #002200;">&#93;</span> forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;name&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>myObj setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>jsonDict objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;city&quot;</span><span style="color: #002200;">&#93;</span> forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;city&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>myObj setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>jsonDict objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;phone&quot;</span><span style="color: #002200;">&#93;</span> forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;phone&quot;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>


<p>&#8230;and on and on and on ad nauseum. It works but it&#8217;s astoundingly ugly. It also makes maintenance more challenging, since any changes to the data structure require changes not only to your Core Data model and related managed object classes but also to your data import code.</p>

<h2>The Easy/Dangerous Way</h2>

<p>Cocoa provides a method that makes this much, much simpler. Thanks to key-value coding there&#8217;s a method in NSObject that reduces the above to a single line:</p>


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


<p>This will run through key/value pairs in <code>jsonDict</code> and set the same key/value pairs on <code>myObj</code>. The only caveat is that the key names must match, but that shouldn&#8217;t be a problem assuming you&#8217;ve named them the same in your data model.</p>

<p>Actually there&#8217;s one more caveat, and it&#8217;s a biggie. In this method, the keys contained in the dictionary determine what keys are used on the managed object. But what if the dictionary contains a key that&#8217;s not part of the entity description? Then your app crashes with an error about how the object is not key-value coding compliant for the key. Using this method here puts your app&#8217;s stability at the mercy of the web service you&#8217;re using. If you don&#8217;t have absolute control over the web service, you&#8217;re running serious risks using this method here. We can do better.</p>

<h2>Inspecting Managed Objects</h2>

<p>Since we&#8217;re using Core Data, we can use <code>NSEntityDescription</code> to inspect a managed object&#8217;s attributes and turn the logic above around. Instead of using the incoming dictionary to determine what key/value pairs to use, we can use the managed object.</p>

<p>You can look up the entity description for a managed object by asking for its <code>entity</code>. That gives you an <code>NSEntityDescription</code> which you can then ask for all kinds of useful information, like what attributes exist. That leads to a safer approach when converting from JSON:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>attributes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>myObj entity<span style="color: #002200;">&#93;</span> attributesByName<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>attribute <span style="color: #a61390;">in</span> attributes<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">id</span> value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>jsonDict objectForKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>value <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">continue</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#91;</span>myObj setValue<span style="color: #002200;">:</span>value forKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>This code iterates over the entity&#8217;s attributes, looks up a key in the dictionary for each of them, and applies that key/value pair to the managed object. That&#8217;s still nice and generic, and has the advantage that changes to incoming data won&#8217;t crash the app any more. It looks up values in the dictionary only for attributes that actually exist in the entity description. Extra dictionary keys are simply ignored.</p>

<p>The check for <code>nil</code> is there because the code does hit <em>all</em> of the entity&#8217;s attributes. If the entity has any attributes that aren&#8217;t present in the incoming data (a &#8220;favorites&#8221; flag, for example) the code would end up setting a nil value for the attribute. That could lead to accidentally wiping out data that you really want to keep.</p>

<h2>Handling Broken and Inconsistent JSON</h2>

<p>The <a href="http://www.json.org/">JSON standard</a> is quite clear about how to distinguish strings from numbers&#8211; basically, strings are surrounded by quotes and numbers are not. JSON <em>web services</em> however, are not always good about following this requirement. And even when they are, they are not always consistent from one record to another.</p>

<p>An example, similar to one I encountered recently: Size information for clothing. Sizes are provided by the web service and are typically something like &#8220;30-32&#8243;, &#8220;34-36&#8243;, etc. These are correctly quoted as strings in the JSON, and the app saves them as string attributes and displays them to the user as is.</p>

<p>But sometimes the size just has one number, e.g. &#8220;8&#8243;, &#8220;10&#8243;, etc. In this case the server drops the quotes, making them numbers. My JSON parser correctly produces an NSNumber. Only I want to save this in my entity&#8217;s string attribute! I can use Objective-C introspection to see if I received an NSString or an NSNumber from my JSON parser, but I also need to know what type the managed object expects for the property. I briefly considered breaking my JSON parser so that it would always return NSString, so at least I would know what to expect from it. Fortunately NSEntityDescription came to the rescue again.</p>

<p>Besides asking the entity description what its attribute names are, you can also inquire about the attribute types configured in the Core Data model. This is returned as an NSAttributeType. Using this, we can expand the code above to handle mismatched data types. It&#8217;s probably a good idea to abstract the code for easy reuse, too, so I&#8217;ll put it in a category on NSManagedObject:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> <span style="color: #400080;">NSManagedObject</span> <span style="color: #002200;">&#40;</span>safeSetValuesKeysWithDictionary<span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>safeSetValuesForKeysWithDictionary<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>keyedValues
<span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>attributes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self entity<span style="color: #002200;">&#93;</span> attributesByName<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>attribute <span style="color: #a61390;">in</span> attributes<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">id</span> value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>keyedValues objectForKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span>;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>value <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #11740a; font-style: italic;">// Don't attempt to set nil, or you'll overwite values in self that aren't present in keyedValues</span>
            <span style="color: #a61390;">continue</span>;
        <span style="color: #002200;">&#125;</span>
        NSAttributeType attributeType <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>attributes objectForKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span> attributeType<span style="color: #002200;">&#93;</span>;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSStringAttributeType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>value stringValue<span style="color: #002200;">&#93;</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><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSInteger16AttributeType<span style="color: #002200;">&#41;</span> || <span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSInteger32AttributeType<span style="color: #002200;">&#41;</span> || <span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSInteger64AttributeType<span style="color: #002200;">&#41;</span> || <span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSBooleanAttributeType<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithInteger<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>value  integerValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</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><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSFloatAttributeType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithDouble<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>value doubleValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
        <span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span>value forKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>


<p>This code inspects the types of both the value found in the dictionary we created from the incoming JSON and the attribute on the managed object, and if there&#8217;s a string/number mismatch it modifies the value to make sure it matches what&#8217;s expected.</p>

<p>This is getting pretty useful. Not only is it a generic JSON-to-NSManagedObject conversion, it also handles mismatches between numeric and string types without needing any entity-specific information. It could be even better, though.</p>

<h2>Handling Dates</h2>

<p>JSON does not have a date type, but dates are nevertheless common in JSON. They&#8217;re just represented as strings using one date format or another. Only you probably want an NSDate, not a string. NSDateFormatter is really useful here, but wouldn&#8217;t it be nice to make the date conversion generic as well, so you don&#8217;t need to special-case your date attribute? Can you see where I&#8217;m going with this?</p>

<p>Having written the category method above, it&#8217;s not much more work to add an optional NSDateFormatter argument, and then to use it whenever an entity&#8217;s attribute expects a date. This modified version adds that argument, and an extra case to the &#8220;else &#8230; if&#8221; chain:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> <span style="color: #400080;">NSManagedObject</span> <span style="color: #002200;">&#40;</span>safeSetValuesKeysWithDictionary<span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>safeSetValuesForKeysWithDictionary<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>keyedValues dateFormatter<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>dateFormatter
<span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>attributes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self entity<span style="color: #002200;">&#93;</span> attributesByName<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>attribute <span style="color: #a61390;">in</span> attributes<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">id</span> value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>keyedValues objectForKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span>;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>value <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">continue</span>;
        <span style="color: #002200;">&#125;</span>
        NSAttributeType attributeType <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>attributes objectForKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span> attributeType<span style="color: #002200;">&#93;</span>;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSStringAttributeType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>value stringValue<span style="color: #002200;">&#93;</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><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSInteger16AttributeType<span style="color: #002200;">&#41;</span> || <span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSInteger32AttributeType<span style="color: #002200;">&#41;</span> || <span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSInteger64AttributeType<span style="color: #002200;">&#41;</span> || <span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSBooleanAttributeType<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithInteger<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>value integerValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</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><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSFloatAttributeType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithDouble<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>value doubleValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</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><span style="color: #002200;">&#40;</span>attributeType <span style="color: #002200;">==</span> NSDateAttributeType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span>dateFormatter <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter dateFromString<span style="color: #002200;">:</span>value<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
        <span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span>value forKey<span style="color: #002200;">:</span>attribute<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>


<h2>Conclusion</h2>

<p>Saving JSON data to a managed object is one of those things that&#8217;s not as easy as it seems at first glance. Making it happen is easy enough, but making it happen safely in maintainable code can quickly get complicated. Fortunately, Core Data has your back and will help you work out what needs to happen along the way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/06/02/saving-json-to-core-data/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Subduing CATiledLayer</title>
		<link>http://www.cimgf.com/2011/03/01/subduing-catiledlayer/</link>
		<comments>http://www.cimgf.com/2011/03/01/subduing-catiledlayer/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 06:01:15 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1321</guid>
		<description><![CDATA[Many technologies we use as Cocoa/Cocoa Touch developers stand untouched by the faint of heart because often we simply don&#8217;t understand them and employing them can seem a daunting task. One of those technologies is found in Core Animation and is referred to as the CATiledLayer. It seems like a magical sort of technology because [...]]]></description>
			<content:encoded><![CDATA[<p>Many technologies we use as Cocoa/Cocoa Touch developers stand untouched by the faint of heart because often we simply don&#8217;t understand them and employing them can seem a daunting task. One of those technologies is found in Core Animation and is referred to as the CATiledLayer. It seems like a magical sort of technology because so much of its implementation is a bit of a black box and this fact contributes to it being misunderstood. CATiledLayer simply provides a way to draw very large images without incurring a severe memory hit. This is important no matter where you&#8217;re deploying, but it especially matters on iOS devices as memory is precious and when the OS tells you to free up memory, you better be able to do so or your app will be brought down. This blog post is intended to demonstrate that CATiledLayer works as advertised and implementing it is not as hard as it may have once seemed.
<span id="more-1321"></span></p>

<p><a href="http://www.cimgf.com/files/BitmapSlice.zip">Download Demo Project</a></p>

<h2>The Trick Is In Listening To The View</h2>

<p>Let me cut to the chase here and clue you in on what you need to do. The easiest way to take advantage of the CATiledLayer is to create a UIView based subclass and override the +layerClass class method to return a [CATiledLayer class].</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> layerClass
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>CATiledLayer class<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Then, you just need to override drawRect: and draw what it tells you to draw. That&#8217;s it! Listen to the UIView. It&#8217;s telling you in drawRect: which rectangle it wants to draw. So while your user is scrolling a scroll view that contains your view, for example, drawRect: will be getting called continuously. You just need to calculate how that rectangle corresponds to the image you&#8217;re wanting to draw.</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>drawRect<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGRect<span style="color: #002200;">&#41;</span>rect
<span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// You cant get the current context if you need it.</span>
   CGContextRef context <span style="color: #002200;">=</span> UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Your drawing code here ...</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>I&#8217;ll show you a fuller implementation of drawRect: later. Feel free to skip there now or even download the demo project if you want to see the project in action. First I&#8217;m going to discuss how we get our tiles and truly take advantage of the memory use reduction we get from the CATiledLayer.</p>

<h2>The Downside Is Tiling the Image</h2>

<p>So, now that you&#8217;ve implemented a UIView derived subclass that overrides drawRect: performance is going to improve drastically, right? Well, unfortunately, not exactly. If you pull the entire image into memory with -imageNamed or even -imageWithContentsOfFile, you&#8217;re going to be up against the exact same memory problem you had before using a tiled layer. So what are the solutions? Well, if there were a way to map tiles to bytes on disk, that would be great, but unfortunately that is far more complicated and I’m not even sure it&#8217;s possible. In the end, we have to actually tile the image manually and store the images on disk to be loaded on demand.</p>

<p>So, the first question I asked when I realized this is can I do the tiling programmatically and write the files out to disk or do I need to slice them up in a photo editor manually? Just like everything in programming, there are tradeoffs between various solutions. If you have a different part of your workflow where it makes sense to tile the images before sending them to the device, I would choose that solution, however, that doesn&#8217;t seem terribly likely. In most cases you&#8217;re probably going to need to tile the images on device programmatically. If that&#8217;s true, then I suggest that you don&#8217;t just tile every image, but rather set a threshold size. If your images reach a certain dimension, only tile those since it will take some time and processing power to do so.</p>

<p>Of course, you&#8217;re going to want to do your tiling on a background thread as to not block your user interface, but here is some basic image tiling code that will write your image tiles to disk. You can place this in an NSOperation or use a block and run it on a background queue.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td 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>saveTilesOfSize<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGSize<span style="color: #002200;">&#41;</span>size 
               forImage<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIImage<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>image 
            toDirectory<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>directoryPath 
            usingPrefix<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>prefix
<span style="color: #002200;">&#123;</span>
  CGFloat cols <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>image size<span style="color: #002200;">&#93;</span>.width <span style="color: #002200;">/</span> size.width;
  CGFloat rows <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>image size<span style="color: #002200;">&#93;</span>.height <span style="color: #002200;">/</span> size.height;
&nbsp;
  <span style="color: #a61390;">int</span> fullColumns <span style="color: #002200;">=</span> floorf<span style="color: #002200;">&#40;</span>cols<span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">int</span> fullRows <span style="color: #002200;">=</span> floorf<span style="color: #002200;">&#40;</span>rows<span style="color: #002200;">&#41;</span>;
&nbsp;
  CGFloat remainderWidth <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>image size<span style="color: #002200;">&#93;</span>.width <span style="color: #002200;">-</span> 
                          <span style="color: #002200;">&#40;</span>fullColumns <span style="color: #002200;">*</span> size.width<span style="color: #002200;">&#41;</span>;
  CGFloat remainderHeight <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>image size<span style="color: #002200;">&#93;</span>.height <span style="color: #002200;">-</span> 
                          <span style="color: #002200;">&#40;</span>fullRows <span style="color: #002200;">*</span> size.height<span style="color: #002200;">&#41;</span>;
&nbsp;
&nbsp;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>cols &gt; fullColumns<span style="color: #002200;">&#41;</span> fullColumns<span style="color: #002200;">++</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>rows &gt; fullRows<span style="color: #002200;">&#41;</span> fullRows<span style="color: #002200;">++</span>;
&nbsp;
  CGImageRef fullImage <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>image CGImage<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> y <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; y &lt; fullRows; <span style="color: #002200;">++</span>y<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> x <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; x &lt; fullColumns; <span style="color: #002200;">++</span>x<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      CGSize tileSize <span style="color: #002200;">=</span> size;
      <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>x <span style="color: #002200;">+</span> <span style="color: #2400d9;">1</span> <span style="color: #002200;">==</span> fullColumns <span style="color: #002200;">&amp;&amp;</span> remainderWidth &gt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// Last column</span>
        tileSize.width <span style="color: #002200;">=</span> remainderWidth;
      <span style="color: #002200;">&#125;</span>
      <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>y <span style="color: #002200;">+</span> <span style="color: #2400d9;">1</span> <span style="color: #002200;">==</span> fullRows <span style="color: #002200;">&amp;&amp;</span> remainderHeight &gt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// Last row</span>
        tileSize.height <span style="color: #002200;">=</span> remainderHeight;
      <span style="color: #002200;">&#125;</span>
&nbsp;
      CGImageRef tileImage <span style="color: #002200;">=</span> CGImageCreateWithImageInRect<span style="color: #002200;">&#40;</span>fullImage, 
                                        <span style="color: #002200;">&#40;</span>CGRect<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span><span style="color: #002200;">&#123;</span>x<span style="color: #002200;">*</span>size.width, y<span style="color: #002200;">*</span>size.height<span style="color: #002200;">&#125;</span>, 
                                          tileSize<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
      <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>imageData <span style="color: #002200;">=</span> UIImagePNGRepresentation<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>UIImage imageWithCGImage<span style="color: #002200;">:</span>tileImage<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
      <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>path <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@/%@%d_%d.png&quot;</span>, 
                        directoryPath, prefix, x, y<span style="color: #002200;">&#93;</span>;
      <span style="color: #002200;">&#91;</span>imageData writeToFile<span style="color: #002200;">:</span>path atomically<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>    
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Let me walk you through this a little bit. We pass in the size of the tiles we want to break our image into. We pass in the image itself, the directory we want to save it to, and finally a prefix that we will use as a unique identifier for the file names for the image in question. We need this so that we can retrieve them again later when we&#8217;re ready display them.</p>

<p>The first thing we do is calculate the number of tiles we&#8217;re going to have in columns and rows by dividing the total width by the tile width and the total height by the tile height. The result is a floating point number. We then get the number of columns and rows that are full sized tiles by using floorf(). We then calculate the width of the last column and the height of last row. Next we iterate through the entire grid of what will soon be tiled images, columns per row. Then we extract the image data at the rect in question and write its contents to disk using an NSData. The filename format we&#8217;re using takes into account the x and y positions in our grid of tiles such that an image would have its tiles named:</p>

<p><pre>
&lt;directory&gt;/&lt;prefix&gt;x_y.png
</pre></p>

<p>Where directory and prefix are the strings passed into the function. The .png extension here is really just for clarity. It is completely unnecessary.</p>

<h2>Implementing Draw Rect</h2>

<p>The first implementation of CATiledLayer expected that you would create a delegate for your layer and then override</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>theContext</pre></div></div>


<p>This was error prone for several reasons. The trouble was you couldn&#8217;t use both UIKit and Core Graphics calls to draw in the layer which people would often do. They would soon start asking <a href="http://stackoverflow.com/questions/2295151/catiledlayer-drawing-crash">why their app was crashing</a> and would discover that the problem could be solved by only drawing using only Core Graphics.</p>

<p>Now, in iOS4, things have gotten much easier. You can simply override drawRect: in your UIView subclass and everything works correctly. To draw my layer correctly, I adapted the drawing code you find in the <a href="https://deimos.apple.com/WebObjects/Core.woa/BrowsePrivately/adc.apple.com.4092349126.04109539109.4144345585?i=1699219987">PhotoScroller sample code from the WWDC 2010 sessions</a> (Link opens iTunes). It looks like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td 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>drawRect<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGRect<span style="color: #002200;">&#41;</span>rect <span style="color: #002200;">&#123;</span>
 	CGContextRef context <span style="color: #002200;">=</span> UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
  CGSize tileSize <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>CGSize<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span><span style="color: #2400d9;">256</span>, <span style="color: #2400d9;">256</span><span style="color: #002200;">&#125;</span>;
&nbsp;
  <span style="color: #a61390;">int</span> firstCol <span style="color: #002200;">=</span> floorf<span style="color: #002200;">&#40;</span>CGRectGetMinX<span style="color: #002200;">&#40;</span>rect<span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> tileSize.width<span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">int</span> lastCol <span style="color: #002200;">=</span> floorf<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>CGRectGetMaxX<span style="color: #002200;">&#40;</span>rect<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> tileSize.width<span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">int</span> firstRow <span style="color: #002200;">=</span> floorf<span style="color: #002200;">&#40;</span>CGRectGetMinY<span style="color: #002200;">&#40;</span>rect<span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> tileSize.height<span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">int</span> lastRow <span style="color: #002200;">=</span> floorf<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>CGRectGetMaxY<span style="color: #002200;">&#40;</span>rect<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> tileSize.height<span style="color: #002200;">&#41;</span>;
&nbsp;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> row <span style="color: #002200;">=</span> firstRow; row &lt;<span style="color: #002200;">=</span> lastRow; row<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> col <span style="color: #002200;">=</span> firstCol; col &lt;<span style="color: #002200;">=</span> lastCol; col<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      UIImage <span style="color: #002200;">*</span>tile <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self tileAtCol<span style="color: #002200;">:</span>col row<span style="color: #002200;">:</span>row<span style="color: #002200;">&#93;</span>;
&nbsp;
      CGRect tileRect <span style="color: #002200;">=</span> CGRectMake<span style="color: #002200;">&#40;</span>tileSize.width <span style="color: #002200;">*</span> col, 
                         tileSize.height <span style="color: #002200;">*</span> row,
                         tileSize.width, tileSize.height<span style="color: #002200;">&#41;</span>;
&nbsp;
      tileRect <span style="color: #002200;">=</span> CGRectIntersection<span style="color: #002200;">&#40;</span>self.bounds, tileRect<span style="color: #002200;">&#41;</span>;
&nbsp;
      <span style="color: #002200;">&#91;</span>tile drawInRect<span style="color: #002200;">:</span>tileRect<span style="color: #002200;">&#93;</span>;
&nbsp;
      <span style="color: #11740a; font-style: italic;">// Draw a white line around the tile border so </span>
      <span style="color: #11740a; font-style: italic;">// we can see it</span>
      <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span> set<span style="color: #002200;">&#93;</span>;
      CGContextSetLineWidth<span style="color: #002200;">&#40;</span>context, <span style="color: #2400d9;">6.0</span><span style="color: #002200;">&#41;</span>;
      CGContextStrokeRect<span style="color: #002200;">&#40;</span>context, tileRect<span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Our view port in the app is set by the frame of the scroll view. This view is a lot larger than a single tile, which we have set to the default size of 256 x 256. That means we need to find all of the tiles that need to be drawn for displaying in the view port. So, we calculate the first column, last column, first row, and last row. This tells us where within the image we need to start and stop drawing. It also tells us which tiles we need to load. Once we&#8217;ve got all of these rows and columns calculated, we can then iterate through them and grab the tile for the current row and column using the same filename format we used to save the files in the first place. The code to load the image tiles looks like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UIImage<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tileAtCol<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>col row<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>row
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>path <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@/%@%d_%d.png&quot;</span>, tileDirectory, tileTag, col, row<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>UIImage imageWithContentsOfFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;  
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Notice we&#8217;re using -imageWithContentsOfFile rather than -imageNamed, since -imageNamed actually caches the image in memory&#8211;which we don&#8217;t want. If we used that, we would be right back at our memory usage issue after scrolling around for a few minutes.</p>

<h2>Conclusion</h2>

<p>Using the CATiledLayer makes a lot of sense when memory is of the essence, which it is much of the time when doing iOS development. Examples from Apple and other places do a good job showing how you can use a tiled layer for use with PDFs, but if you want to tile an image, things are a little more complicated. I hope this post has served to help you better understand this powerful Core Animation layer. Until next time.</p>

<p><a href="http://www.cimgf.com/files/BitmapSlice.zip">Download Demo Project</a></p>

<h2>Notes on the Demo Project</h2>

<p>When running on the device the image I am tiling is just too large to be tiled completely before the app uses up too much memory and is killed. You will probably want to run in the simulator to see the tiling finish. As noted in the code comments, you un-comment the tiling code and do a first run with the app allowing it to finish tiling. Then, stop the app and re-comment that tiling code and it will just load and display the tiles it created without having to go through that tiling again. I suppose I could have made the tiling code get called in response to a button tap or something like that, but I&#8217;ll leave that as an exercise for the reader. Contact me through the comments below if you have any problems or questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/03/01/subduing-catiledlayer/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Passing around a NSManagedObjectContext on iOS</title>
		<link>http://www.cimgf.com/2011/01/07/passing-around-a-nsmanagedobjectcontext-on-the-iphone/</link>
		<comments>http://www.cimgf.com/2011/01/07/passing-around-a-nsmanagedobjectcontext-on-the-iphone/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 19:23:46 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1274</guid>
		<description><![CDATA[This article is reprinted from the MDN The documentation on Core Data for the iPhone has lead to some confusion about how best to use Core Data on a Cocoa Touch device. One particular section seems to be the most confusing, specifically: A view controller typically shouldn’t retrieve the context from a global object such [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This article is reprinted from the MDN</strong></p>

<p>The documentation on Core Data for the iPhone has lead to some confusion about how best to use Core Data on a Cocoa Touch device.  One particular section seems to be the most confusing, specifically:</p>

<blockquote>
  <p>A view controller typically shouldn’t retrieve the context from a global object such as the application delegate. This tends to make the application architecture rigid. Neither should a view controller typically create a context for its own use. This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.</p>
  
  <p>When you create a view controller, you pass it a context. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It’s typically the responsibility of the application delegate to create a context to pass to the first view controller that’s displayed.</p>
</blockquote>

<p>The idea behind this section is the issue of rigidity.  Ideally, each view controller should be an island on its own.  It should not rely on its parent, nor should it rely on the Application Delegate.  Once a view controller is pushed onto the screen it should ideally be its own master.</p>

<h2>Why Rigidity is bad</h2>

<p>It is fairly common when designing a Cocoa Touch application to &#8220;hard code&#8221; everything.  Take the following navigation controller design:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2011/01/Image1.png" alt="Navigation Controller Design" title="Standard Navigation Controller Design" /></p>

<p>When this design, it is common to code each view controller and make it &#8220;aware&#8221; of its parent.  In that design, it would be common to see view controller B call methods or call back (to its delegate) view controller A.  While there is nothing technically wrong with this design, it is very rigid.  It is nearly impossible to either move view controller B to another location in the stack or to reuse view controller B somewhere else.  This is the trap that the documentation is trying to help new developers avoid.</p>

<h2>Solution One</h2>

<p>Again using a standard/normal navigation controller design, it is expected that the detail flows from left to right.  The left most (or root) view controller contains the most vague information and the right most (or deepest) view controller contains the greatest detail.</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2011/01/Image2.png" alt="UIFetchedResultsController" title="UIFetchedResultsController" /></p>

<p>In this case then the best solution is to use a <code>UIFetchedResultsController</code>.  This controller can be considered a thin layer between the view controllers and the Core Data bits.  The advantage is that the <code>UIFetchedResultsController</code> is designed to work with tables.  The other advantage is that your least detailed view (the root most likely) can listen as the delegate of the <code>UIFetchedResultsController</code> for changes and update itself.</p>

<p>In this design, however, instead of passing around a context, you would hand off just the entity that the child view controller needs to know about.  The Core Data Recipes example provided by Apple illustrates this design quite well.</p>

<p>How does this break rigidity?  Each view controller, from the root on down, only knows what is passed into it.  The root gets the <code>UIFetchedResultsController</code> passed into it.  The child views only get the items it cares about passed into it.  None of them care what their parent view controller is.  There is no call back to a parent.</p>

<h2>Solution two</h2>

<p>What happens when we don&#8217;t have a typical navigation controller design?  Perhaps a child view can pop up a modal view that displays different information.  Perhaps a child view, for whatever reason needs to access information that cannot be directly passed into it every time.</p>

<p>In these cases there are a few different options.</p>

<h3>View already has a <code>NSManagedObject</code></h3>

<p>Following our example above, lets say that view controller C needs to create a new object.  Perhaps it is a detail view of a recipe and the user wants to add a new recipe type (perhaps she is a vegan and just discovered there is no vegan type in the list).  In this case we have passed in an entity (the recipe) but not a reference to the <code>NSManagedObjectContext</code>.  Fortunately this solution is easy to fix.  The <code>NSManagedObject</code> retains a reference to its <code>NSManagedObjectContext</code> internally and we can access it.  Therefore we can easily retrieve the <code>NSManagedObjectContext</code> from the <code>NSManagedObject</code> and create the new Type entity and pass it to the modal child or whatever our design calls for.</p>

<p>This again avoids rigidity because the view controller that represents the entity does not need to call up to a parent object or the <code>UIApplication</code> delegate.  It is self contained and only manages view controllers that are down stream from it.</p>

<h3>View does not have a <code>NSManagedObject</code></h3>

<p>In this situation things are <em>slightly</em> more complicated.  In this case we want to create a <code>@property</code> for the <code>NSManagedObjectContext</code> and require that our creator set the property.</p>

<pre><code>@interface MyViewController : ViewController
{
    NSManagedObjectContext *moc;
}

@property (nonatomic, retain) NSManagedObjectContext *moc;

@end
</code></pre>

<p>Again, the view controller is an island of its own because it does not care where that <code>NSManagedObjectContext</code> came from.  All it knows is that it is required for the view to function.  It does not care of it is a new <code>NSManagedObjectContext</code> specifically created for its use (perhaps for a cancelable edit tree) or if it is the same <code>NSManagedObjectContext</code> that has been passed around since the launch of the application.  All it knows is that it has the elements it needs to perform its function.</p>

<p>By making the <code>NSManagedObjectContext</code> a settable property we can also transplant the view easily.  If, at some point in the project lifecycle, we decide that it makes more sense to have the following design:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2011/01/Image3.png" alt="Modal View Controller" title="Modal View Controller" /></p>

<p>Taking from Apple&#8217;s Recipes Application, perhaps we decide that moving from the table view directly to the image of the recipe is more pleasing to the users and that when they want to see how to make it they can &#8220;flip&#8221; the image over and see the detail.</p>

<p>Making this change with each view controller being an island is quite simple.  We just rearrange the views without having to worry too much about breaking the application.</p>

<h2>Solution three</h2>

<p>Up until now we have been looking at just a navigation controller design.  But what about tab bars?  In the situation of a tab bar we again want to avoid rigidity because it is even more common that tabs will get moved around.</p>

<p>The solution to this is to again use a <code>@property</code> for the <code>NSManagedObjectContext</code> and require that the creator set this property before the view is displayed on screen.  If you are creating the tabs in code this is trivial because you are already calling init on the view controller and you can add one more line of code after the init to set the property.</p>

<p>If the user interface is being developed mostly in Interface Builder it is slightly more tricky.  Personally I am not a fan of creating navigation controllers or tab bar controllers in Interface Builder.  However if that is the design then I would recommend referencing the view controllers as properties and passing along the context upon initialization of the application.  It may be possible to do this entirely in Interface Builder but I am not comfortable enough to recommend that as a solution.</p>

<h2>Conclusion</h2>

<p>The overall idea behind this article is to keep each view controller separate from anything up stream or in a different silo.  This will make the design far more flexible in the long run.  Any time that you feel the &#8220;need&#8221; to pass in a parent view controller to a child view controller, reconsider the design.  Consider using a <code>@protocol</code> delegate design or NSNotification calls instead.  Keep each view controller as its own private island.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/01/07/passing-around-a-nsmanagedobjectcontext-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Core Data and Encryption</title>
		<link>http://www.cimgf.com/2010/07/15/core-data-and-encryption/</link>
		<comments>http://www.cimgf.com/2010/07/15/core-data-and-encryption/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 21:20:14 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1161</guid>
		<description><![CDATA[Just a quick post to point out a great article written by Nick Harris of NewsGator fame. He has looked into the issues with Core Data and encryption. Core Data and Enterprise iPhone Applications &#8211; Protecting Your Data It has always been a difficult question and fortunately Apple has addressed it for us. Even better, [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick post to point out a great article written by Nick Harris of <a href="http://www.newsgator.com">NewsGator</a> fame.  He has looked into the issues with Core Data and encryption.</p>

<p><a href="https://nickharris.wordpress.com/2010/07/14/core-data-and-enterprise-iphone-applications-protecting-your-data/">Core Data and Enterprise iPhone Applications &#8211; Protecting Your Data</a></p>

<p>It has always been a difficult question and fortunately Apple has addressed it for us.  Even better, Nick has shared the code so we don&#8217;t even need to try and discover the solution ourselves.</p>

<p>Thanks Nick!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/07/15/core-data-and-encryption/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Differentiating Tap Counts on iOS [UPDATED]</title>
		<link>http://www.cimgf.com/2010/06/14/differentiating-tap-counts-on-ios/</link>
		<comments>http://www.cimgf.com/2010/06/14/differentiating-tap-counts-on-ios/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 23:02:08 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1072</guid>
		<description><![CDATA[In your iPhone/iPad apps you often need to know how many times your user tapped in a view. This can be challenging because, though the user may have tapped twice, you will receive the event and it will look like they tapped once as well as twice. If the user triple-tapped, you will get the [...]]]></description>
			<content:encoded><![CDATA[<p>In your iPhone/iPad apps you often need to know how many times your user tapped in a view. This can be challenging because, though the user may have tapped twice, you will receive the event and it will look like they tapped once as well as twice. If the user triple-tapped, you will get the event for one tap, two taps, and three taps. It can get a little frustrating, but the trick is timing. You simply have to wait a period of time to see if another tap comes. If it does, you cancel the action spawned by the first tap. If it doesn&#8217;t you allow the action to run. There&#8217;s a few little nuances to getting it to work, but it can be done. Here is how.
<span id="more-1072"></span></p>

<h2>Overriding Touch Event Handlers</h2>

<p>In order to know how many times your user tapped, you listen for the events in the various touch handlers. Let start with -touchesEnded. This is where we will determine how many taps we received and respond accordingly. Consider the following code.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td 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>touchesEnded<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSSet</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>touches withEvent<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIEvent<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event 
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>touches.count <span style="color: #002200;">==</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>  
    <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>touches anyObject<span style="color: #002200;">&#93;</span> tapCount<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span>self handleDoubleTap<span style="color: #002200;">&#93;</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><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>touches anyObject<span style="color: #002200;">&#93;</span> tapCount<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #2400d9;">3</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span>self handleTripleTap<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">else</span>
    <span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span>self handleSingleTap<span style="color: #002200;">&#93;</span>; 
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>If you place a breakpoint inside each of the code blocks for the three tap counts, you will find that in the case where you triple tap, it will break in all three. If you double tap, it will break in both the double tap and single tap and of course if you single tap, it will break in the single tap branch.</p>

<p>In most cases, this is not desirable. You will likely want a clean differentiation between each touch as each tap count will likely mean something different. So how can we fix this? The trick is to use <em>-peformSelector:withObject:afterDelay</em> and then canceling the perform action if a new action occurs. Got it?</p>

<h2>Wait For It&#8230;</h2>

<p>If you call the method directly as we did in the sample code above, there is no way to delay when it runs nor is there a way to cancel it should another tap be received. Both of these things are necessary. If you think about it, waiting to run our <em>-handleSingleTap</em> method until a certain amount of time passes helps make sure it actually was a double tap. If the user taps once and nothing else occurs, we&#8217;re safe to run the <em>-handleSingleTap</em> code. If another tap is received in the mean time, however, we can cancel the action from the first tap. The way we do this is by changing our <em>-touchesEnded:</em> code to something like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td 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>touchesEnded<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSSet</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>touches withEvent<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIEvent<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event 
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>touches.count <span style="color: #002200;">==</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>  
    <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>touches anyObject<span style="color: #002200;">&#93;</span> tapCount<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span>self performSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleDoubleTap<span style="color: #002200;">&#41;</span>
                 withObject<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                 afterDelay<span style="color: #002200;">:</span><span style="color: #2400d9;">0.35</span><span style="color: #002200;">&#93;</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><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>touches anyObject<span style="color: #002200;">&#93;</span> tapCount<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #2400d9;">3</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span>self handleTripleTap<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">else</span>
    <span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span>self performSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleSingleTap<span style="color: #002200;">&#41;</span>
                 withObject<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                 afterDelay<span style="color: #002200;">:</span><span style="color: #2400d9;">0.35</span><span style="color: #002200;">&#93;</span>; 
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Notice that we are delaying 350 milliseconds to see if another event occurs. You should also notice that we still call <em>-handleTripleTap</em> directly without using <em>-performSelector:withObject:afterDelay</em>. This is because it has now been isolated as a distinct event. If we get a triple tap, we&#8217;re pretty well assured now that a double or single tap event was not actually run as those events will have been cancelled. So how does that work? How do we cancel them?</p>

<h2>Canceling The Action</h2>

<p>Now that we are waiting around to see if another tap event occurs, we need to override the <em>-touchesBegan:</em> method. It will look something like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td 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>touchesBegan<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSSet</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>touches withEvent<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIEvent<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSObject</span> cancelPreviousPerformRequestsWithTarget<span style="color: #002200;">:</span>self
                                           selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleSingleTap<span style="color: #002200;">&#41;</span>
                                             object<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSObject</span> cancelPreviousPerformRequestsWithTarget<span style="color: #002200;">:</span>self
                                           selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleDoubleTap<span style="color: #002200;">&#41;</span>
                                             object<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>The method <em>-cancelPreviousPerformRequestsWithTarget:selector:object:</em> is able to determine which action you want to cancel and then cancel it preventing the selectors, <em>-handleSingleTap</em> or <em>-handleDoubleTap</em> from being called&#8211;assuming the second or third taps occurred within the allocated 350 milliseconds. That&#8217;s all there is to it.</p>

<h2>There *Is* a Catch</h2>

<p>That is all there is to it, however, you have to be careful if you intend to pass parameters to your selectors. If you use a selector that takes a parameter so that you have to call something with <em>-performSelector:withObject:afterDelay:</em> passing an object to the second parameter, you will need <em>that</em> object or one identical to it in your call to cancel the action with <em>-cancelPreviousPerformRequestsWithTarget:selector:object:</em>. It must be able to evaluate to true when <em>equals</em> is called on the object passed into the <em>object</em> parameter. This can be tricky, but you can overcome it in one of two ways using an ivar:</p>

<ul>
<li><p>Create an ivar to hold onto the variable that you will use as a parameter to the cancel when you first pass it to the <em>-performSelector:withObject:afterDelay:</em> call.</p></li>
<li><p>Create an ivar to hold onto the variable when you first enter touches ended and call <em>-performSelector:withObject:afterDelay</em> passing it nil for the <em>object</em> parameter. Then, grab the ivar when you need it in your handler code. The cancel call can then take nil for its <em>object</em> parameter.</p></li>
</ul>

<p>These points are crucial if you are intending to pass parameters as the cancel will fail if you try to pass a parameter and it doesn&#8217;t match what you used in your call to <em>-performSelector:withObjecct:afterDelay:</em>. The only parameter that doesn’t matter is the <em>afterDelay:</em> param.</p>

<h2>Conclusion</h2>

<p>I&#8217;m finding the need to differentiate tap counts more and more often so this post is really as much a way for me to keep a journal of things I need to do frequently as it is to help others figure things out too. I hope it&#8217;s been helpful to you. Until next time.</p>

<h1>Update</h1>

<p>So, apparently Gesture Recognizers do address this issue. I had looked at them as a possible solution, but ran into the same differentiation problems, hence this blog post. However, <a href="http://twitter.com/aclark">Ashley Clark</a> pointed me to the <em><a href="http://developer.apple.com/iphone/library/documentation/uikit/reference/UIGestureRecognizer_Class/Reference/Reference.html#//apple_ref/occ/instm/UIGestureRecognizer/requireGestureRecognizerToFail:">-requireGestureRecognizerToFail:</a></em> method, which apparently enables you to have this cancellation functionality by creating a dependency between recognizers. The code to take advantage of it looks something like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">UITapGestureRecognizer <span style="color: #002200;">*</span>tripleTap <span style="color: #002200;">=</span> 
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITapGestureRecognizer alloc<span style="color: #002200;">&#93;</span>
 initWithTarget<span style="color: #002200;">:</span>self action<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleTripleTap<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>tripleTap setNumberOfTapsRequired<span style="color: #002200;">:</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self view<span style="color: #002200;">&#93;</span> addGestureRecognizer<span style="color: #002200;">:</span>tripleTap<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>tripleTap release<span style="color: #002200;">&#93;</span>;
&nbsp;
UITapGestureRecognizer <span style="color: #002200;">*</span>doubleTap <span style="color: #002200;">=</span> 
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITapGestureRecognizer alloc<span style="color: #002200;">&#93;</span>
 initWithTarget<span style="color: #002200;">:</span>self action<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleDoubleTap<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>doubleTap setNumberOfTapsRequired<span style="color: #002200;">:</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>doubleTap requireGestureRecognizerToFail<span style="color: #002200;">:</span>tripleTap<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self view<span style="color: #002200;">&#93;</span> addGestureRecognizer<span style="color: #002200;">:</span>doubleTap<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>doubleTap release<span style="color: #002200;">&#93;</span>;
&nbsp;
UITapGestureRecognizer <span style="color: #002200;">*</span>singleTap <span style="color: #002200;">=</span> 
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITapGestureRecognizer alloc<span style="color: #002200;">&#93;</span>
 initWithTarget<span style="color: #002200;">:</span>self action<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleSingleTap<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>singleTap setNumberOfTapsRequired<span style="color: #002200;">:</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// Unnecessary since it's the default</span>
<span style="color: #002200;">&#91;</span>singleTap requireGestureRecognizerToFail<span style="color: #002200;">:</span>doubleTap<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self view<span style="color: #002200;">&#93;</span> addGestureRecognizer<span style="color: #002200;">:</span>singleTap<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>singleTap release<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>So, if your project is 3.2 and later, use gesture recognizers. The effect is about the same, but the code is quite a bit cleaner.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/06/14/differentiating-tap-counts-on-ios/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Creating a NSManagedObject that is Cross Platform</title>
		<link>http://www.cimgf.com/2010/02/18/creating-a-nsmanagedobject-that-is-cross-platform/</link>
		<comments>http://www.cimgf.com/2010/02/18/creating-a-nsmanagedobject-that-is-cross-platform/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 18:37:33 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=950</guid>
		<description><![CDATA[An interesting question came up on Stackoverflow today so I decided to expound upon it in a short blog post. A situation that I believe we are going to be seeing more and more often is one where application developers are writing multiple &#8220;versions&#8221; of their applications to be used on the desktop, their iPhone [...]]]></description>
			<content:encoded><![CDATA[<p>An interesting question came up on Stackoverflow today so I decided to expound upon it in a short blog post.</p>

<p>A situation that I believe we are going to be seeing more and more often is one where application developers are writing multiple &#8220;versions&#8221; of their applications to be used on the desktop, their iPhone and now the iPad.</p>

<p>Because of that situation, it is becoming even more important that we write as much portable code as possible.  Fortunately, our model can be completely portable between the two platforms.</p>

<p><span id="more-950"></span></p>

<h2>NSImage vs UIImage</h2>

<p>The primary issue with creating a portable model and model objects is images.  Now, if the images are stored on disk and only referenced in your Core Data model, then you don&#8217;t have an issue.  Since you are storing the images on disk in a portable format (png, jpeg, etc.) then they will port right over to all of the platforms you are targeting.</p>

<p>But what happens when you are working with small images that should be stored within Core Data?  Simple right, just use a transformable data type and stick the image right in there.</p>

<p>Unfortunately that fails in the portability department.</p>

<p>The issue is that on the desktop you are storing a serialized version of the NSImage instance and on the other devices you are storing an instance of UIImage.  Two different data structures that are incompatible.  So what is the right answer?</p>

<p>Store the images in a portable format even in Core Data.</p>

<p>But that is hard right?</p>

<p>Fortunately if we create concrete subclasses of any entity that needs to store images it is a small amount of code and some conditional compiling.</p>

<h3><code>MyEntityWithAnImage.h</code></h3>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">&nbsp;
<span style="color: #a61390;">@interface</span> MyEntityWithAnImage <span style="color: #002200;">:</span> <span style="color: #400080;">NSManagedObject</span>
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #6e371a;">#ifdef IPHONEOS_DEPLOYMENT_TARGET</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIImage <span style="color: #002200;">*</span>image;
<span style="color: #6e371a;">#else</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSImage</span> <span style="color: #002200;">*</span>image;
<span style="color: #6e371a;">#endif</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>In the header we declare the same property and the use some conditional compiling to determine which definition should be used.  On the desktop the property image will return an NSImage and on the other platforms it will return a UIImage.  But how do we work this magic?</p>

<h3><code>MyEntityWithAnImage.m</code></h3>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#ifdef IPHONEOS_DEPLOYMENT_TARGET</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setImage<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIImage<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>image
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>self willChangeValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> UIImagePNGRepresentation<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>;
  <span style="color: #002200;">&#91;</span>myManagedObject setImage<span style="color: #002200;">:</span>data<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self setPrimitiveValue<span style="color: #002200;">:</span>data forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self didChangeValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UIImage<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>image
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>self willAccessValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  UIImage <span style="color: #002200;">*</span>image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIImage imageWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self primitiveValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self didAccessValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> image;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #6e371a;">#else</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setImage<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSImage</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>image
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>self willChangeValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSBitmapImageRep</span> <span style="color: #002200;">*</span>bits <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>image representations<span style="color: #002200;">&#93;</span> objectAtIndex<span style="color: #002200;">:</span> <span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>bits representationUsingType<span style="color: #002200;">:</span>NSPNGFileType properties<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>myManagedObject setImage<span style="color: #002200;">:</span>data<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self setPrimitiveValue<span style="color: #002200;">:</span>data forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self didChangeValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSImage</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>image
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>self willAccessValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSImage</span> <span style="color: #002200;">*</span>image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSImage</span> alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self primitiveValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self didAccessValueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>image autorelease<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #6e371a;">#endif</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>Here we are overriding the dynamic accessors and implementing our own.  We are fully KVO compliant and notify when we are accessing or changing the image value.</p>

<p>In the desktop version we grab the bitmap image representation and then get the PNG representation of it and store that representation into Core Data as NSData.</p>

<p>In the Cocoa Touch version we are using the C function which returns the PNG representation of the UIImage instance directly.  We are again storing that as NSData into our image property.</p>

<p>In both cases the getter reverses the process by loading the NSData back into the appropriate image instance.</p>

<h2>Wrap Up</h2>

<p>This makes the code external to our <code>NSManagedObject</code> completely unaware of the actual data storage and they just know that they are getting back the object they need to work with.</p>

<p>BTW, if anyone knows of another pre-processor variable that I should be using for this instead of <code>IPHONEOS_DEPLOYMENT_TARGET</code> please let me know.  I am not 100% confident that <code>IPHONEOS_DEPLOYMENT_TARGET</code> is the best variable to be testing against.</p>

<p>Do you like this idea, hate it?  Tell me in person at <a href='http://nsconference.com/'>NSConferenceUSA</a>!  Tickets are still available and it will be great to see you there.</p>

<p>If that is too soon then please catch me at <a href='http://360idev-MarcusZ.eventbrite.com/'>360 iDev</a> in April!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/02/18/creating-a-nsmanagedobject-that-is-cross-platform/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Fun With UIButtons and Core Animation Layers</title>
		<link>http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/</link>
		<comments>http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 06:53:03 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=861</guid>
		<description><![CDATA[Upon first glance, the UIButton class doesn&#8217;t seem to provide what you might expect in terms of customization. This often causes developers to resort to creating buttons in an image editor and then specifying that in the Background field in Interface Builder. This is a fine solution and will likely give you what you need, [...]]]></description>
			<content:encoded><![CDATA[<p>Upon first glance, the UIButton class doesn&#8217;t seem to provide what you might expect in terms of customization. This often causes developers to resort to creating buttons in an image editor and then specifying that in the Background field in Interface Builder. This is a fine solution and will likely give you what you need, but with Core Animation layers there is a simpler way to achieve the look you want without having to create an image. This post will demonstrate how.
<span id="more-861"></span></p>

<h2>Setting a Background Color</h2>

<p><a href="http://www.cimgf.com/wp-content/uploads/2010/01/solidcolorbuttons.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2010/01/solidcolorbuttons.png" alt="Solid Background Buttons" title="Solid Background Buttons" width="291" height="93" class="alignleft size-full wp-image-866" /></a></p>

<p>In Interface Builder, you can specify a background color for your button if you are using the &#8216;Custom&#8217; button setting, but when you run the application, the button will display as a block with no rounded corners. This is because custom buttons don&#8217;t really have any default attributes defined. It&#8217;s completely up to you to define them. Core Animation layers can help.</p>

<blockquote><strong>Note:</strong> Before I get into the source code, I want to remind you that you&#8217;ll need to add the QuartzCore framework to your project and #import &lt;QuartzCore/QuartzCore.h&gt; into one of your header files to have Core Animation layer support. I normally add this import statement to my precompiled header (.pch) file.</blockquote>

<p>What Interface Builder doesn&#8217;t give you, you can still take advantage of by writing a little bit of code. For example, if you want your custom button to have a red background color with rounded corners and a border, you need to define an outlet in your view controller where the button will be referenced and set the following attributes on the UIButton&#8217;s <em>layer</em>.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>button layer<span style="color: #002200;">&#93;</span> setCornerRadius<span style="color: #002200;">:</span>8.0f<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>button layer<span style="color: #002200;">&#93;</span> setMasksToBounds<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>button layer<span style="color: #002200;">&#93;</span> setBorderWidth<span style="color: #002200;">:</span>1.0f<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>With this code the layer gets a corner radius of 8.0 and the -setMasksToBounds: tells the button&#8217;s layer to mask any layer content that comes below it in the layer tree. This is necessary in order for the layer to mask off the rounded corners.</p>

<p>Finally, set the border width to 1.0 to display an outline around the button. The default color for this border is black. You can change it to anything you like using -setBorderColor: on the layer passing it a CGColorRef (e.g. [[UIColor greenColor] CGColor] would give you a green border).</p>

<blockquote><strong>iPhone Development Protip:</strong> Rounding corners is possible on any UIView based view. All UIViews have a root layer. You simply call  <strong>-setCornerRadius:</strong> and <strong>-setMasksToBounds:</strong> on the view&#8217;s layer and your corners will be rounded. It is <em>that</em> simple.</blockquote>

<p>You can set the background color in Interface Builder or in code&#8211;whichever you prefer. There are two ways to do this in code. One using the layer and one using the UIView call to -setBackgroundColor:.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Core Animation way</span>
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>button layer<span style="color: #002200;">&#93;</span> setBackgroundColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor redColor<span style="color: #002200;">&#93;</span> CGColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">// UIView way</span>
<span style="color: #002200;">&#91;</span>button setBackgroundColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor redColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>The main difference between the two is that the layer works with a CGColorRef while the UIView works with a UIColor. It&#8217;s a subtle difference, but one that you should know.</p>

<h2>Gradient Buttons Rule</h2>

<p><a href="http://www.cimgf.com/wp-content/uploads/2010/01/colorfulbuttonsapp1.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2010/01/colorfulbuttonsapp1-156x300.png" alt="Colorful Buttons App" title="Colorful Buttons App" width="156" height="300" class="alignleft size-medium wp-image-872" /></a></p>

<p>The demo app uses some ultra-bright gaudy looking color gradients just for effect. I suggest you don&#8217;t use something so loud and obnoxious. A more subtle difference between colors will look better. Of course this is subjective, so do what you like.</p>

<p>To achieve this gradient look, I use a <a href="http://developer.apple.com/iphone/library/documentation/GraphicsImaging/Reference/CAGradientLayer_class/Reference/Reference.html">CAGradientLayer</a> and add it to the root of the button&#8217;s layer tree. In fact, for the demo application, I created a UIButton derived class that encapsulates the gradient layer creation and drawing. Here is its implementation:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;ColorfulButton.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> ColorfulButton
&nbsp;
<span style="color: #a61390;">@synthesize</span> _highColor;
<span style="color: #a61390;">@synthesize</span> _lowColor;
<span style="color: #a61390;">@synthesize</span> gradientLayer;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>awakeFromNib;
<span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Initialize the gradient layer</span>
    gradientLayer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>CAGradientLayer alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Set its bounds to be the same of its parent</span>
    <span style="color: #002200;">&#91;</span>gradientLayer setBounds<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self bounds<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Center the layer inside the parent layer</span>
    <span style="color: #002200;">&#91;</span>gradientLayer setPosition<span style="color: #002200;">:</span>
                CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self bounds<span style="color: #002200;">&#93;</span>.size.width<span style="color: #002200;">/</span><span style="color: #2400d9;">2</span>,
                       <span style="color: #002200;">&#91;</span>self bounds<span style="color: #002200;">&#93;</span>.size.height<span style="color: #002200;">/</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Insert the layer at position zero to make sure the </span>
    <span style="color: #11740a; font-style: italic;">// text of the button is not obscured</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span> insertSublayer<span style="color: #002200;">:</span>gradientLayer atIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Set the layer's corner radius</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span> setCornerRadius<span style="color: #002200;">:</span>8.0f<span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Turn on masking</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span> setMasksToBounds<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Display a border around the button </span>
    <span style="color: #11740a; font-style: italic;">// with a 1.0 pixel width</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span> setBorderWidth<span style="color: #002200;">:</span>1.0f<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawRect<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGRect<span style="color: #002200;">&#41;</span>rect;
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>_highColor <span style="color: #002200;">&amp;&amp;</span> _lowColor<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// Set the colors for the gradient to the </span>
        <span style="color: #11740a; font-style: italic;">// two colors specified for high and low</span>
        <span style="color: #002200;">&#91;</span>gradientLayer setColors<span style="color: #002200;">:</span>
                     <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObjects<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>_highColor CGColor<span style="color: #002200;">&#93;</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>_lowColor CGColor<span style="color: #002200;">&#93;</span>, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#91;</span>super drawRect<span style="color: #002200;">:</span>rect<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setHighColor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIColor<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>color;
<span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Set the high color and repaint</span>
    <span style="color: #002200;">&#91;</span>self set_highColor<span style="color: #002200;">:</span>color<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span> setNeedsDisplay<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setLowColor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIColor<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>color;
<span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Set the low color and repaint</span>
    <span style="color: #002200;">&#91;</span>self set_lowColor<span style="color: #002200;">:</span>color<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self layer<span style="color: #002200;">&#93;</span> setNeedsDisplay<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Release our gradient layer</span>
    <span style="color: #002200;">&#91;</span>gradientLayer release<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>Now, when I&#8217;m creating a button in Interface Builder, I can make it of class <em>ColorfulButton</em> and then set an outlet for it in my view controller.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2010/01/colorfulbuttonclass.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2010/01/colorfulbuttonclass-300x184.png" alt="" title="Colorful Button Class Attribute" width="300" height="184" class="alignleft size-medium wp-image-881" /></a></p>

<p>If I don&#8217;t set colors for a gradient, it will just render the button using the background color I specify for it in Interface Builder. If, however, I want to take advantage of the gradient capability, I set the gradient colors in my view controller as shown in the following code snippet:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td 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>viewDidLoad <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>super viewDidLoad<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>button1 setHighColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor redColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>button1 setLowColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor orangeColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>button2 setHighColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor blueColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>button2 setLowColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor lightGrayColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>button3 setHighColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor yellowColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>button3 setLowColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor purpleColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>button4 setHighColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor cyanColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>button4 setLowColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor magentaColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>These are the first four buttons you see in the demo app screenshot above. The buttons are declared in the view controller header as show in the following snippet:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;UIKit/UIKit.h&gt;</span>
<span style="color: #6e371a;">#import &quot;ColorfulButton.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> ColorfulButtonsViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&#123;</span>
    IBOutlet ColorfulButton <span style="color: #002200;">*</span>button1;
    IBOutlet ColorfulButton <span style="color: #002200;">*</span>button2;
    IBOutlet ColorfulButton <span style="color: #002200;">*</span>button3;
    IBOutlet ColorfulButton <span style="color: #002200;">*</span>button4;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>The <strong>CAGradientLayer</strong> supports adding an array of colors and will automatically render them linearly with equal distribution. It will also allow you to specify the distribution pattern, however, to keep it simple here I just use two colors represented by the upper color called <em>highColor</em> and the lower color called <em>lowColor</em>. If you want to add more complex gradients, you could modify my <em>ColorfulButton</em> class to take an array of colors as well. I leave this as an exercise for the reader.</p>

<h2>Conclusion</h2>

<p>Next time you need to customize a button, consider using Core Animation layers first. You may be surprised at what all you can achieve without having to resort to creating images to use as the button background. I have included the source code for this blog post below. Let me know if you have any thoughts or questions about it in the comments section. Until next time.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2010/01/ColorfulButtons.zip'>Colorful Buttons Demo Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>The PragPub Magazine</title>
		<link>http://www.cimgf.com/2010/01/09/the-pragpub-magazine/</link>
		<comments>http://www.cimgf.com/2010/01/09/the-pragpub-magazine/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 16:21:59 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=859</guid>
		<description><![CDATA[Last month I was given the opportunity to write an article for The Pragmatic Programmers great magazine called &#8220;PragPub&#8221;. I am happy to say that the article I wrote for them was published in this month&#8217;s edition. The article, titled &#8220;Touching the Core&#8221;, is a walk through Apple&#8217;s great addition to the Core Data API [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I was given the opportunity to write an article for The Pragmatic Programmers great magazine called &#8220;PragPub&#8221;.  I am happy to say that the article I wrote for them was published in this month&#8217;s edition.  The article, titled &#8220;Touching the Core&#8221;, is a walk through Apple&#8217;s great addition to the Core Data API for the iPhone.</p>

<p>Specifically this article walks through using the NSFetchedResultsController and some best practices in its use.  The magazine is available for free on their website, <a href="http://pragprog.com/magazines">The Pragmatic Bookshelf</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/01/09/the-pragpub-magazine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically save the dSYM files.</title>
		<link>http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/</link>
		<comments>http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 02:28:50 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=843</guid>
		<description><![CDATA[For those not aware, when you compile an Objective-C application, whether it be for the desktop or for Cocoa Touch devices, the debugging symbols are stripped out of the binaries. Therefore, unlike other languages such as Java, when a crash occurs, there is virtually no way to determine where the crash occurred. However, when the [...]]]></description>
			<content:encoded><![CDATA[<p>For those not aware, when you compile an Objective-C application, whether it be for the desktop or for Cocoa Touch devices, the debugging symbols are stripped out of the binaries.  Therefore, unlike other languages such as Java, when a crash occurs, there is virtually no way to determine where the crash occurred.  However, when the applications are compiled, a dSYM bundle is generated.  This bundle allows us to match up the debugging symbols with the application&#8217;s crash log to help determine the cause of the crash.</p>

<p><span id="more-843"></span></p>

<p>The issue, however, is that the dSYM file must match the binary exactly<sup>[<a name="id394062" href="#ftn.id394062">1</a>]</sup>.  <del>I have not even had luck with pulling the code out of version control and compiling a second time to get the files to match up.</del>  Therefore, we need to store these dSYM files for every build that gets handed off to someone else.  For Cocoa Touch development this means every ad hoc build and every release build.  This can be a pain.  </p>

<p>To solve this problem I wrote a script that is added as the last build phase of all my iPhone projects.  The script will move the dSYM bundle into the project directory in a directory cleverly called &#8220;dSYM&#8221;.  In addition the script will check the bundle into git (after confirming the project is maintained in a git repository) and commit just that bundle.  Also, since the file is always named the same thing, it renames the file using the current date and time so that no two bundles have the same file name.</p>

<h2 id="failure_checks">Failure checks</h2>

<p>The first thing the script does is determine if it should run.</p>

<p><pre><code>if [ "$BUILD_STYLE" == "Debug" ]; then
  echo "Skipping debug"
  exit 0;
fi
</code></pre></p>

<p>The first part of the script checks to see if the build style is Debug.  Since all debug builds run just on the developer&#8217;s device and still contain the debug symbols, they can be safely ignored.</p>

<p><pre><code>if [ "$EFFECTIVE_PLATFORM_NAME" == "-iphonesimulator" ]; then
  echo "Skipping simulator build"
  exit 0;
fi
</code></pre></p>

<p>The second step is to check to see if the build is against the simulator.  Again, we have no interest in storing the symbol files for these builds.</p>

<h2 id="move_the_file">Move the file</h2>

<p>Since the location of the file is determined at build time and can vary from developer to developer (as well as machine to machine) I use the environmental variables that are part of the build.</p>

<p><pre><code>SRC_PATH=${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}
RELATIVE_DEST_PATH=dSYM/${EXECUTABLE_NAME}.$(date +%Y%m%d%H%M%S).app.dSYM
DEST_PATH=${PROJECT_DIR}/${RELATIVE_DEST_PATH}
echo "moving ${SRC_PATH} to ${DEST_PATH}"</p>

<p>mv "${SRC_PATH}" "${DEST_PATH}"
</code></pre></p>

<p>The next step is to build up the paths of where the file is currently and where we are going to move it to.  I like to store these in variables so that I can print them out to the console in case something goes wrong.  </p>

<h2 id="commit_it_to_version_control">Commit it to version control</h2>

<p>Every project is part of version control right? (<em>RIGHT</em>?)</p>

<p><pre><code>if [ -f ".git/config" ]; then
  git add "${RELATIVE_DEST_PATH}"
  git commit -m "Added dSYM file for ${BUILD_STYLE} build" \
      "${RELATIVE_DEST_PATH}"
fi
</code></pre></p>

<p>The final part only occurs if the project is part of a git repository.  If it is then the bundle is added to git and then just that bundle is committed with a simple message.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Although I have recently been having issues getting <code>symbolicatecrash</code> to work properly, eventually either I or someone else will get it working again and at that time these files will be invaluable in tracking down crashes.</p>

<p>The final script is attached.  I normally add the file to the project and then have a script phase that just calls this script file.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2009/12/Move_dSYM_To_Storage.sh.zip" title="Move_dSYM_To_Storage.sh.zip">Move_dSYM_To_Storage.sh.zip</a></p>

<div class="footnote"><p>
<sup>[<a name="ftn.id394062" href="#id394062">1</a>]</sup>Mach-o objects have an embedded uuid which must match the uuid of the dsym files. That&#8217;s why recompiling doesn&#8217;t work. &#8211;<a href='http://twitter.com/iamleeg/status/6998511425'>Graham Lee</a></p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>UITableViewCell Dynamic Height</title>
		<link>http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/</link>
		<comments>http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 05:35:58 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=732</guid>
		<description><![CDATA[At first glance setting a height dynamically for table view cells seems a little daunting and the first most obvious answers that come to mind are not necessarily correct. In this post I will show you how to set your table view cell heights dynamically based upon the text content without subclassing UITableViewCell. You can [...]]]></description>
			<content:encoded><![CDATA[<p>At first glance setting a height dynamically for table view cells seems a little daunting and the first most obvious answers that come to mind are not necessarily correct. In this post I will show you how to set your table view cell heights dynamically based upon the text content without subclassing UITableViewCell. You can subclass it, however, doing so does not make the code much cleaner as setting the height is done in your delegate for the table view itself rather than the cell anyhow. Read on to see what you need to know to make dynamic cell height sizing a breeze.
<span id="more-732"></span>
There are probably numerous reasons why you might want dynamic heights for your table view cells, but the one I&#8217;ve run into most is the need to resize because I am displaying lists of text objects with varying lengths. When the text is short, it might fit in the normal cell label, however, if the text gets longer, you will want to resize the cell so that you can display the complete content. I&#8217;ve distilled the process of resizing table cells to a few rules of thumb. Here they are:</p>

<ul>
<p><li>Create, configure, and add a <strong>UILabel</strong> as a subview of the <i>contentView</i> in the cell.</p>
<p><li>Calculate the height in the UITableView delegate method, &#8211; (CGFloat)tableView:(UITableView*)tableView <strong>heightForRowAtIndexPath</strong>:(NSIndexPath *)indexPath;</li></p>
<p><li>Calculate the frame for the UILabel in the UITableView delegate method, &#8211; (UITableViewCell*)tableView:(UITableView*)tableView <strong>cellForRowAtIndexPath</strong>:(NSIndexPath *)indexPath;</li></p>
</ul>

<p>I am going to cover each of these rules in detail, but take a look at the output of the example project in the screenshot.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2009/09/dynamicheights.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/09/dynamicheights.png" alt="Dynamic Heights" title="Dynamic Heights" class="alignleft size-full wp-image-737" /></a></p>

<h2>Add a UILabel to the Cell</h2>

<p>In simpler table view based applications, you can simply set the text of the table view cell&#8217;s text label like this:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>cell textLabel<span style="color: #002200;">&#93;</span> setText<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Text for the current cell here.&quot;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>


<p>Doing so might make you think that you can manipulate the UILabel that the cell uses, however, I&#8217;ve found my attempts to change the UILabel&#8217;s frame get ignored completely, so it is not a good candidate for use with our dynamic resizing code.</p>

<p>Instead what we need to do is programatically create a UILabel and add it to the cell&#8217;s content view. Do this in the call to -cellForRowAtIndexPath. Use something like the following code:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tv cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSIndexPath</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
  UITableViewCell <span style="color: #002200;">*</span>cell;
  UILabel <span style="color: #002200;">*</span>label <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
  cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>tv dequeueReusableCellWithIdentifier<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Cell&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>cell <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>
    cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITableViewCell alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>CGRectZero reuseIdentifier<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Cell&quot;</span><span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
    label <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UILabel alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>CGRectZero<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setLineBreakMode<span style="color: #002200;">:</span>UILineBreakModeWordWrap<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setMinimumFontSize<span style="color: #002200;">:</span>FONT_SIZE<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setNumberOfLines<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setFont<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIFont systemFontOfSize<span style="color: #002200;">:</span>FONT_SIZE<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setTag<span style="color: #002200;">:</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>cell contentView<span style="color: #002200;">&#93;</span> addSubview<span style="color: #002200;">:</span>label<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>This is not the completed code as you&#8217;ll notice that we have initialized the label only when the cell needs created for the first time, that is if (cell == nil) after a call to -dequeueReusableCellWithIdentifier. There are two points I want to address in relation to this. First, notice the label has a <strong>tag</strong> associated with it after a call to -setTag:1. This will be used in the case where the cell is not equal to nil after a call to -dequeueReusableCellWithIdentifier. In that case we will need to get a handle to the label by calling [cell viewWithTag:1] which will return the view that we associated with that tag. Second, notice that we have added our label to the cell&#8217;s content view with a call to [[cell contentView] addSubview:label]. This is done when the label is initialized and should only be done once. Adding it each time this method is called will add the label again to the subviews array. We will come back to this code to finish it in a minute, but first let&#8217;s take a look at how we can set the height for our cell now that our label has been added.</p>

<h2>Calculate the Cell Height</h2>

<p>In a complex cell, your calculations could get a bit challenging, however, you only need to worry with the items that will change in height. In our example, the only item you need to deal with is the label that we added. We calculate the height of the cell by determining the size of the text based on the length of the text and the font we intend to use. The <strong>NSString</strong> class provides a method called -sizeWithFont that enables us to obtain this size. The following code show how we implement our call to -heightForRowAtIndexPath:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>CGFloat<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView heightForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSIndexPath</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath;
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>items objectAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>indexPath row<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  CGSize constraint <span style="color: #002200;">=</span> CGSizeMake<span style="color: #002200;">&#40;</span>CELL_CONTENT_WIDTH <span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>CELL_CONTENT_MARGIN <span style="color: #002200;">*</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>, 20000.0f<span style="color: #002200;">&#41;</span>;
&nbsp;
  CGSize size <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>text sizeWithFont<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIFont systemFontOfSize<span style="color: #002200;">:</span>FONT_SIZE<span style="color: #002200;">&#93;</span> constrainedToSize<span style="color: #002200;">:</span>constraint lineBreakMode<span style="color: #002200;">:</span>UILineBreakModeWordWrap<span style="color: #002200;">&#93;</span>;
&nbsp;
  CGFloat height <span style="color: #002200;">=</span> MAX<span style="color: #002200;">&#40;</span>size.height, 44.0f<span style="color: #002200;">&#41;</span>;
&nbsp;
  <span style="color: #a61390;">return</span> height <span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>CELL_CONTENT_MARGIN <span style="color: #002200;">*</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>You will notice that we have several constants we are using to calculate the size of our cell. These are defined as follows:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define FONT_SIZE 14.0f</span>
<span style="color: #6e371a;">#define CELL_CONTENT_WIDTH 320.0f</span>
<span style="color: #6e371a;">#define CELL_CONTENT_MARGIN 10.0f</span></pre></td></tr></table></div>


<p>The constant <strong>CELL_CONTENT_WIDTH</strong> is the width of the entire cell. <strong>CELL_CONTENT_MARGIN</strong> is the margin we want to use all the way around the cell as the content inset, and of course <strong>FONT_SIZE</strong> is the size of the font we want to use for the label text.</p>

<p>The first place we use these is to create a constraint with the content width. Notice that CGSizeMake takes as its first parameter the total content width minus the margin times 2. This subtracts the margin from the left and the margin from the right from the total width to have the actual width of the label. The second parameter is just a maximum number we provide. The call to -sizeWithFont will set this to the actual height in the next line. This call to -sizeWithFont calculates the size according to the constant UILineBreakModeWordWrap which causes it to return the correct size for word wrap&#8211;which is why the width is important to get right. Next we set our height for the cell using a call to the MAX macro. This will ensure that our cell height will never be shorter than the default 44 pixels as MAX returns the larger of the two variables. Finally, we add our margin height back into the height for both top and bottom (hence x 2) and then return the result.</p>

<p>To help visualize how the margin is working, take a look at the following screenshot to see what each label looks like with a border around it. Turning this on with a call to [[label layer] setBorderWidth:2.0f] on the UILabel we added in the previous section makes it clear where the margins are.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2009/09/dynamicheights02.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/09/dynamicheights02.png" alt="Dynamic Heights Outline" title="Dynamic Heights Outline" class="alignleft size-full wp-image-744" /></a></p>

<h2>Calculate the UILabel Frame and Set It</h2>

<p>The same calculation we used to determine the height in the previous section is the code we use to set the frame for the UILabel we added in the beginning. To complete this tutorial we will finish out our implementation of -cellForRowAtIndexPath with the following code.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tv cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSIndexPath</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
  UITableViewCell <span style="color: #002200;">*</span>cell;
  UILabel <span style="color: #002200;">*</span>label <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
  cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>tv dequeueReusableCellWithIdentifier<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Cell&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>cell <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>
    cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITableViewCell alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>CGRectZero reuseIdentifier<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Cell&quot;</span><span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
    label <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UILabel alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>CGRectZero<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setLineBreakMode<span style="color: #002200;">:</span>UILineBreakModeWordWrap<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setMinimumFontSize<span style="color: #002200;">:</span>FONT_SIZE<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setNumberOfLines<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setFont<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIFont systemFontOfSize<span style="color: #002200;">:</span>FONT_SIZE<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>label setTag<span style="color: #002200;">:</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>label layer<span style="color: #002200;">&#93;</span> setBorderWidth<span style="color: #002200;">:</span>2.0f<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>cell contentView<span style="color: #002200;">&#93;</span> addSubview<span style="color: #002200;">:</span>label<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#125;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>items objectAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>indexPath row<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  CGSize constraint <span style="color: #002200;">=</span> CGSizeMake<span style="color: #002200;">&#40;</span>CELL_CONTENT_WIDTH <span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>CELL_CONTENT_MARGIN <span style="color: #002200;">*</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>, 20000.0f<span style="color: #002200;">&#41;</span>;
&nbsp;
  CGSize size <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>text sizeWithFont<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIFont systemFontOfSize<span style="color: #002200;">:</span>FONT_SIZE<span style="color: #002200;">&#93;</span> constrainedToSize<span style="color: #002200;">:</span>constraint lineBreakMode<span style="color: #002200;">:</span>UILineBreakModeWordWrap<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>label<span style="color: #002200;">&#41;</span>
    label <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>UILabel<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>cell viewWithTag<span style="color: #002200;">:</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>label setText<span style="color: #002200;">:</span>text<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>label setFrame<span style="color: #002200;">:</span>CGRectMake<span style="color: #002200;">&#40;</span>CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH <span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>CELL_CONTENT_MARGIN <span style="color: #002200;">*</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>, MAX<span style="color: #002200;">&#40;</span>size.height, 44.0f<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Just remember that anything done within the if (cell == nil) block is initialization code and should only be done when the cell is first created. Anything done outside of the block will be used every time the -cellForRowAtIndexPath is called, which is any time the data gets reloaded or the view gets scrolled.</p>

<p>That being said, you will see that the only thing we do every time it gets called is setting the text of the current item and setting the label&#8217;s frame for the current item (lines 32 and 33). Notice that we got a handle to our UILabel by calling [cell viewWithTag:1] (lines 29 and 30) in the case where the label is nil in subsequent/non-initialization calls to this method. You will notice that our frame calculation code is exactly the same as what we used in the previous section to determine the row height.</p>

<h2>Conclusion</h2>

<p>Calculating dynamic cell heights is really not too hard. If you have a very complex cell, just remember that all you really need to calculate is the height based up a width that shouldn&#8217;t change and the size of the text of a certain font (unless of course you support both portrait and landscape modes&#8211;which makes things a little more challenging. I will, however, leave this as an exercise for the reader). If you find yourself wondering where your actual frame is displaying for a given view, just turn on the view border by calling [[view layer] setBorderWidth:2.0f]. This will help you see what is going on and give you the ability get to the bottom of your display problems quicker. Until next time.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2009/08/DynamicHeights.zip'>DynamicHeights Demo Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>UITabBarController with UINavigationController Using Interface Builder</title>
		<link>http://www.cimgf.com/2009/06/25/uitabbarcontroller-with-uinavigationcontroller-using-interface-builder/</link>
		<comments>http://www.cimgf.com/2009/06/25/uitabbarcontroller-with-uinavigationcontroller-using-interface-builder/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 03:18:52 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=590</guid>
		<description><![CDATA[I&#8217;ve seen a good bit of sample code that shows how to implement using a UINavigationController in a view controller that is managed by a UITabBarController, but I haven&#8217;t seen much on how to do it with Interface Builder. Turns out that it&#8217;s pretty simple and I&#8217;m going to show you how. TabBarNavigator Demo Project [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve seen a good bit of sample code that shows how to implement using a UINavigationController in a view controller that is managed by a UITabBarController, but I haven&#8217;t seen much on how to do it with Interface Builder. Turns out that it&#8217;s pretty simple and I&#8217;m going to show you how.
<span id="more-590"></span></p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2009/06/tabbarnavigator.zip'>TabBarNavigator Demo Project</a></p>

<p>To get started, create a new project in Xcode. Select the <em>Tab Bar Application</em> template and click <em>Choose&#8230;</em>.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2009/06/newproject.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/newprojectsmall.png" alt="newprojectsmall" title="newprojectsmall" width="384" height="308" class="alignnone size-full wp-image-599" /></a></p>

<p>Name the project, TabBarNavigator and click <em>Save</em></p>

<div id="attachment_596" class="wp-caption alignnone" style="width: 310px"><a href="http://www.cimgf.com/wp-content/uploads/2009/06/tabbarnavigator.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/tabbarnavigator-300x221.png" alt="TabBarNavigator Project" title="TabBarNavigator Project" width="300" height="221" class="size-medium wp-image-596" /></a><p class="wp-caption-text">TabBarNavigator Project</p></div>

<h2>Change The Controller Type</h2>

<ol>
<li><p>In Xcode, expand the <em>Resources</em> group in the <em>Groups and Files</em> view and double-click <em>MainWindow.xib</em> to open the xib in Interface Builder</p></li>

<li><p>When Interface builder opens, change the xib <em>View Mode</em> to the tree view mode and expand your <em>Tab Bar Controller</em> item.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/mainwindow.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/mainwindow-300x213.png" alt="MainWindow.xib" title="MainWindow.xib" width="300" height="213" class="alignnone size-medium wp-image-602" /></a>
</p></li>

<li><p>Make sure that the <em>Tab View Controller</em> object is selected. In the object inspector switch to the <em>Attributes</em> tab and change the <em>Class</em> for the <em>First</em> controller from <em>View Controller</em> to <em>Navigation Controller</em>.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/navcontrollerselect.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/navcontrollerselect-218x300.png" alt="Select Navigation Controller" title="Select Navigation Controller" width="218" height="300" class="alignnone size-medium wp-image-603" /></a>
</p></li>

<li><p>You will notice back in the <em>MainWindow.xib</em> window that the view controller for <em>First View</em> is now a <em>UINavigationController</em>. Expand the UINavigationController item now.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/mainwindow2.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/mainwindow2-300x213.png" alt="New UINavigationController" title="New UINavigationController" width="300" height="213" class="alignnone size-medium wp-image-604" /></a></p></li>

<li><p>Now select the <em>View Controller</em> that is a child of our new <em>UINavigationController</em>. Click on the <em>Identity</em> tab of the object inspector and change the <em>Class</em> to <em>FirstViewController</em>.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/identity.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/identity.png" alt="First View Controller Identity" title="First View Controller Identity" width="236" height="285" class="alignnone size-full wp-image-611" /></a></p></li>

<li><p>Click on the <em>Navigation Item</em> that is a child of the <em>First View Controller</em> and change the <em>Title</em> in the <em>Attributes</em> tab of the object inspector to <em>&#8220;First&#8221;</em>.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/navitemattributes.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/navitemattributes.png" alt="Navigation Item Attributes" title="Navigation Item Attributes" width="236" height="142" class="alignnone size-full wp-image-613" /></a></p>
</li>

<li><p>Save your changes in Interface Builder, switch back to Xcode and <em>Build &amp; Go</em>. You should see something like the following in your <em>First</em> view tab.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/firstviewsimulator.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/firstviewsimulator-161x300.png" alt="First View in Simulator" title="First View in Simulator" width="161" height="300" class="alignnone size-medium wp-image-615" /></a></p>
</li>

<li><p>Notice that there is a Toolbar visible at the bottom of the first view. If you would like to hide this, go back into Interface Builder and select the <em>Navigation Controller</em> In the object inspector, uncheck the <em>Shows Toolbar</em> checkbox.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/uncheckshowstoolbar.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/uncheckshowstoolbar.png" alt="Uncheck Shows Toolbar" title="Uncheck Shows Toolbar" width="236" height="201" class="alignnone size-full wp-image-617" /></a></p>
</li>
</ol>

<h2>Pushing a New Controller</h2>

<p>Before we create a new view controller, let&#8217;s set up our <em>FirstViewController</em> to create an event that will trigger pushing the new controller. Since our FirstView was not created with a xib, let&#8217;s create one and then add actions and outlets to it.</p>

<ol>
<li><p>In Xcode, right-click or ctrl-click the <em>Resources</em> group and select <em>Add | New File&#8230;</em>. In the ensuing dialog, select <em>View XIB</em> in the <em>User Interface</em> section of <em>iPhone OS</em> templates and click <em>Next</em>. Name the XIB <em>FirstView</em> and click <em>Finish</em>.</p></li>

<li><p>Double-click the new XIB to open it in Interface Builder and select the <em>Identity</em> tab after you have made sure that <em>File&#8217;s Owner</em> is selected. Change the <em>Class</em> field to <em>FirstViewController</em>.</p>
</li>

<li><p>Ctrl-click and drag a connection from the <em>File&#8217;s Owner</em> object to the <em>View</em> object in the main window for our XIB and select <em>view</em> in the ensuing pop up menu.</p></li>

<li><p>From the <em>Object Library</em> drag and drop a button onto the view. Double-click the button and give it the title <em>&#8220;Push&#8221;</em>. Save your changes in Interface Builder and switch back to Xcode.
<a href="http://www.cimgf.com/wp-content/uploads/2009/06/pbutton.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/pbutton-161x300.png" alt="&quot;Push&quot; Button" title="&quot;Push&quot; Button" width="161" height="300" class="alignnone size-medium wp-image-633" /></a>
</p>
</li>

<li><p>Open the file <em>FirstViewController.h</em> and add an action so that the header looks like this:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;UIKit/UIKit.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> FirstViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&#123;</span>
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>push<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>



</p>
</li>

<li><p>Open the file <em>FirstViewController.m</em> and implement the action so that the code looks like this:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;FirstViewController.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> FirstViewController
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>push<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender
<span style="color: #002200;">&#123;</span>
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>



<blockquote><strong>Note:</strong> You can safely delete all of the view controller template code which I have done in this example. Don&#8217;t worry. You won&#8217;t hurt anything.</blockquote></p>
</li>
</ol>

<p>We will come back to the push implementation after we have created our new view controller that we are going to push.</p>

<h2>Create the New View Controller</h2>

<p>We are now going to create the new view controller that will be displayed when we tap our &#8220;Push&#8221; button in the <em>FirstViewController</em>.</p>

<ol>
<li><p>In Xcode, right-click or ctrl-click the <em>Classes</em> group and select <em>Add | New File&#8230;</em>. In the ensuing dialog, select <em>UIViewController subclass</em> in the <em>Cocoa Touch Class</em> category of the <em>iPhone OS</em> templates. Make sure <em>With XIB for user interface</em> is checked and click <em>Next</em>. Name the file <em>NewViewController.m</em> and click <em>Finish</em>.</p></li>

<li><p>For organization purposes, move the newly created <em>NewViewController.xib</em> file into the <em>Resources</em> group. Then double-click it to open it in Interface Builder.</p></li>

<li><p>In Interface Builder, drag a <em>UILabel</em> onto the view and give it the title <em>&#8220;New View Controller&#8221;</em>. Save the file and switch back to Xcode.</p></li>

<li><p>Open the file <em>FirstViewController.m</em> again and implement controller push code so that it looks like this:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;FirstViewController.h&quot;</span>
<span style="color: #6e371a;">#import &quot;NewViewController.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> FirstViewController
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>push<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender
<span style="color: #002200;">&#123;</span>
  NewViewController <span style="color: #002200;">*</span>controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>NewViewController alloc<span style="color: #002200;">&#93;</span> initWithNibName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;NewViewController&quot;</span> bundle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self navigationController<span style="color: #002200;">&#93;</span> pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>, controller <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>



<blockquote>Don&#8217;t forget to #import &#8220;NewViewController.h&#8221;</blockquote></p>
</li>

<li><p>To connect our button to the push action, double-click the <em>FirstView.xib</em> file in the <em>Resources</em> group to open it in Interface Builder.</p></li>

<li><p>Ctrl-click and drag a connection from the <em>&#8220;Push&#8221;</em> button in our view to the <em>File&#8217;s Owner</em> object and select <em>push:</em> in the ensuing pop up menu. Save your changes in Interface Builder. Switch back to Xcode and <em>Build &amp; Go</em>.</p></li>

<li><p>Additionally, you can give your <em>New View Controller</em> a title by implementing <em>-viewDidLoad</em>. Just open your <em>NewViewController.m</em> file and uncomment the <em>-viewDidLoad</em> code making it look like the following:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;NewViewController.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> NewViewController
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad <span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>self setTitle<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;New View&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>super viewDidLoad<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc <span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>



</p>
</li>
</ol>

<p><a href="http://www.cimgf.com/wp-content/uploads/2009/06/newview.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2009/06/newview-161x300.png" alt="New View Controller" title="New View Controller" width="161" height="300" class="alignnone size-medium wp-image-630" /></a></p>

<p>And that&#8217;s pretty much all there is to it. There are a lot of steps here, but I think you&#8217;ll see that setting up your application to implement both a UITabBarController and a UINavigationController is pretty straight forward.</p>

<h2>Conclusion</h2>

<p>How best to organize your views in an iPhone application is a design process. Often applications will have a lot of data for your users to access and it will be up to you to find the best way to organize it. Being able to utilize both a tab bar and a navigation controller can really help in this process. Until next time.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2009/06/tabbarnavigator.zip'>TabBarNavigator Demo Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/06/25/uitabbarcontroller-with-uinavigationcontroller-using-interface-builder/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Magical iPhone View Controllers</title>
		<link>http://www.cimgf.com/2009/05/11/magical-iphone-view-controllers/</link>
		<comments>http://www.cimgf.com/2009/05/11/magical-iphone-view-controllers/#comments</comments>
		<pubDate>Mon, 11 May 2009 16:19:53 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Undocumented]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=531</guid>
		<description><![CDATA[Update: This is documented behavior. Every now and again while doing development you stumble upon something that makes you go, hmmmm. Those are normally the moments at which you have to ask yourself, &#8220;is this a bug or a feature&#8221;. If it&#8217;s a bug, then you should file a radar with Apple, however, what if [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update: This is <a href="http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/initWithNibName:bundle:">documented behavior</a></strong>.</p>

<p>Every now and again while doing development you stumble upon something that makes you go, hmmmm. Those are normally the moments at which you have to ask yourself, &#8220;is this a bug or a feature&#8221;. If it&#8217;s a bug, then you should file a radar with Apple, however, what if it&#8217;s a feature? You blog about it, of course!</p>

<p>I have done a bit less iPhone development than Marcus, so he was a little stumped while looking through some of my code where I created a view controller using a simple alloc/init. Most interestingly is that fact that the app works. It loads the correct nib and displays the view just fine without any trouble. Notice I said alloc/init and not alloc/initWithNibName. How can this possibly work? How did my controller &#8220;know&#8221; which view to use?
<span id="more-531"></span></p>

<p>Well, the answer is pretty simple, but not immediately obvious. I could try to act like I meant to use an undocumented feature because I&#8217;m just that cool, but the fact of the matter is I was in band. Marching band, even. Band people aren&#8217;t cool. Though the color guard thought we were cool. But I digress. I just inadvertently added the alloc/init code without thinking and never looked back since the view loaded and displayed just fine. After renaming the nib/xib in the project and in doing so causing the view to fail to load properly we were able to determine that there must be some underlying <em>feature</em> of view controllers where it will automagically look for a view based upon its own name.</p>

<h2>Say Huh?</h2>

<p>Yep. That&#8217;s correct. If you create a view controller with the name <em>MySpiffyViewController</em>, for example, and instantiate it with alloc/init in your code, it will assume that the nib you want is actually called <em>MySpiffyView</em>. Spiffy eh? Some people may call this a bug, but the fact that it works this way shows that it was intentional. Now, I recommend that you steer clear of intentionally creating your view controllers this way as Apple may decide it&#8217;s a bug after all and change (fix?) it in a future release. It is however an interesting undocumented feature at the moment.</p>

<h2>You Can Duplicate It</h2>

<p>Here are the steps if you want to try this yourself. Of course, you can just <a href="#example">download the example project below</a> if you don&#8217;t want to go through the steps.</p>

<ol>
<li>In Xcode, press Command+Shift+N to open the New Project templates and select <strong>View-based Application</strong> in the <strong>iPhone OS</strong> category and click <strong>Choose&#8230;</strong>.</li>
<br />
<li>Name the project <strong>SpiffyView</strong> and click <strong>Save</strong></li>
<br />
<li>The first thing we need to do is change our code in the app delegate (called SpiffyViewAppDelegate.m) to add a UINavigationController.


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td 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>applicationDidFinishLaunching<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application <span style="color: #002200;">&#123;</span>    
    UINavigationController <span style="color: #002200;">*</span>navController <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UINavigationController alloc<span style="color: #002200;">&#93;</span> initWithRootViewController<span style="color: #002200;">:</span>viewController<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>navController navigationBar<span style="color: #002200;">&#93;</span> setBarStyle<span style="color: #002200;">:</span>UIBarStyleBlackTranslucent<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>window addSubview<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>navController view<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>window makeKeyAndVisible<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>



This will enable us to navigate to the new view we create next.
</li>
<br />
<li>Press Command+N and select <strong>View XIB</strong> under the <strong>User Interfaces</strong> category. Click <strong>Next</strong>. Name the file <strong>MySpiffyView</strong> and click <strong>Finish</strong></li>
<br />
<li>Press Command+N again and select <strong>UIViewController subclass</strong> under the <strong>Cocoa Touch Classes</strong> category. Click <strong>Next</strong>. Name the file <strong>MySpiffyViewController.m</strong> and click <strong>Finish</strong>.</li>
<br />
<li>Next we need to create an action in the view controller created by the project template called SpiffyViewViewController. Add the following code to the respective .m and .h files as follows.


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add this to your SpiffyViewViewController.h</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>showSpiffyView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Add this to your SpiffyViewViewController.m. Make sure you #import &quot;MySpiffyViewController.h&quot; as well.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>showSpiffyView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">id</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MySpiffyViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self navigationController<span style="color: #002200;">&#93;</span> pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>, controller <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


</li>
<br />
<li>Now we need to connect a button to the action. In your project under resources, double-click SpiffyViewViewController.xib to open it in Interface Builder.</li>
<br />
<li>In Interface Builder, drag a button onto the view and change its text to &#8220;Spiffy View&#8221;</li>
<br />
<li>Now, Control-Click and drag a connection from your button in the view, to the <strong>File&#8217;s Owner</strong> and select <strong>showSpiffyView:</strong> in the ensuing menu. Save the file in IB.</li>
<br />
<li>Now, back in Xcode, double click MySpiffyView.xib to open it in Inteface Builder.</li>
<br />
<li>Change the <strong>File&#8217;s Owner</strong> class to MySpiffyViewController in the <strong>Identity</strong> tab of the <strong>Inspector</strong>.</li>
<br />
<li>Drag a label onto the view. Double click it to edit it and change the text to &#8220;This is the super spiffy view.&#8221; Save the file in IB.</li>
<br />
<li>Everything should be hooked up now. Go back to Xcode and &#8220;Build &amp; Go&#8221;. Your app should load in the simulator. When you see the &#8220;Spiffy View&#8221; button, click it and it should show your new view!!</li>
<br />
</ol>

<h2>Conclusion</h2>

<p>So how is that working? The only answer is there must be some underlying code that the view controller is using to locate its nib. Remember, we never told our controller what nib to use. We simply called alloc/init and voila, it works!!</p>

<p>If you think I ought to register this as a bug with Apple, let me know your thoughts in the comments. Oh and one other thing. I may have been in band, but I married a smokin&#8217; hot cheerleader. Take that all you cool people. ;-) Until next time.
<br /><br /><br />
<a name="example">
<a href='http://www.cimgf.com/wp-content/uploads/2009/05/spiffyview.zip'>Example Project SpiffyView.zip</a>
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/05/11/magical-iphone-view-controllers/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Landscape Tab Bar Application for the iPhone</title>
		<link>http://www.cimgf.com/2008/11/13/landscape-tab-bar-application-for-the-iphone/</link>
		<comments>http://www.cimgf.com/2008/11/13/landscape-tab-bar-application-for-the-iphone/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 02:53:06 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=361</guid>
		<description><![CDATA[As you develop applications for the iPhone, you will likely use the project templates provided in Xcode. One such template, called &#8220;Tab Bar Application&#8221; helps you get a tab bar application set up quickly, but by default the application it generates only supports portrait mode for display. So how can you make the application also [...]]]></description>
			<content:encoded><![CDATA[<p>As you develop applications for the iPhone, you will likely use the project templates provided in Xcode. One such template, called &#8220;Tab Bar Application&#8221; helps you get a tab bar application set up quickly, but by default the application it generates only supports portrait mode for display. So how can you make the application also support landscape or even only support landscape? In this post we will address that question.
<span id="more-361"></span>
To duplicate the problem, create a new tab bar application in Xcode. To do so,</p>

<ol>
<li>Press Command-Shift-N and select Tab Bar Application in the iPhone OS | Application templates. Click Choose&#8230;</li>
<li>Provide a name for the project. I chose &#8220;Tab Test&#8221;</li>
<li>Click Save</li>
</ol>

<p>The first thing you&#8217;ll notice is that the template has generated two classes for us. One called FirstViewController, which is used to control the first view (ya think?). The other is called Tab_TestAppDelegate which is our application delegate&#8211;the entry point and main controller class for our application.</p>

<p>Take a look at the stub code generated in the FirstViewController. It is commented out for the most part, but you&#8217;ll notice that there is a method in there that gives us what we want for allowing different orientations for our application. In particular, we are interested in <strong>-shouldAutorotateToInterfaceOrientation</strong>. Uncomment that code and have it simply return YES. This setting will enable the controller to support all orientations.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Override to allow orientations other than the default portrait orientation.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>shouldAutorotateToInterfaceOrientation<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIInterfaceOrientation<span style="color: #002200;">&#41;</span>interfaceOrientation <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Return YES for supported orientations</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>This <em>should</em> cause our view to change orientation when the device is turned. Build and run the application using the simulator. Once the simulator has loaded the application, select Hardware | Rotate Left. You will notice that while the device did rotate, the view did not. Why is this?</p>

<h2>All Or None</h2>

<p>Remember that the default tab bar application template creates a tab bar component with <strong>two</strong> views. While we have explicitly told the FirstViewController object to allow all orientations, we have not done so with our second view. The way the tab bar controller works is that if <strong>any</strong> of the view controllers have a limitation on the orientation of the view, then <strong>all</strong> views are constrained by the same limitation.</p>

<p>What this means is that all view controllers must override the call to <strong>-shouldAutorotateToInterfaceOrientation</strong> to return the appropriate setting&#8211;YES to allow all. In our default tab bar app, we have not assigned the second view to a controller because we have not defined one, so where is it getting its controller from? Well, the answer is found in interface builder. If you double-click MainWindow.xib in the Resources group of the Xcode project, Interface Builder will load. Click on the tab for the first view in the main window, and then select the Identity tab in the Inspector, you&#8217;ll see what is going on.</p>

<div id="attachment_368" class="wp-caption alignleft" style="width: 310px"><a href="http://www.cimgf.com/wp-content/uploads/2008/11/firstview.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2008/11/firstview-300x245.png" alt="FirstViewController" title="FirstViewController" width="300" height="245" class="size-medium wp-image-368" /></a><p class="wp-caption-text">FirstViewController</p></div>

<p>Notice in the first view <strong>Class</strong> field, it is set to <strong>FirstViewController</strong>. Take a close look now at our second view by clicking the second tab.</p>

<div id="attachment_370" class="wp-caption alignleft" style="width: 310px"><a href="http://www.cimgf.com/wp-content/uploads/2008/11/secondview.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2008/11/secondview-300x245.png" alt="SecondView Controller" title="SecondView Controller" width="300" height="245" class="size-medium wp-image-370" /></a><p class="wp-caption-text">SecondView Controller</p></div>

<p>Notice that the class we&#8217;re using here is the base UIViewController class. This is our view&#8217;s controller. It only provides the base functionality&#8211;which is to say it doesn&#8217;t provide a whole lot. Furthermore it implements the default functionality. The default setting for the orientation of a view controller is portrait only. In other words, only derivative classes are going to be able to override <strong>-shouldAutorotateToInterfaceOrientation</strong> and set it to something other than the default.</p>

<p>If you want your application to be able to support more than the default portrait orientation, all of your tab views must have their own view controller that overrides <strong>-shouldAutorotateToInterfaceOrientation</strong></p>

<h2>Conclusion</h2>

<p>The iPhone is a fun and interesting computing platform. It is very powerful, but it has a lot of nuances that make it fairly different from what you may be used to on OS X. The trick is to remember the principles you&#8217;ve already learned in Cocoa, MVC in particular, and you should be able to deal with the nuances and make them submit to your own will. Until next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/11/13/landscape-tab-bar-application-for-the-iphone/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Cocoa Touch Tutorial: iPhone Application Example</title>
		<link>http://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/</link>
		<comments>http://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 15:34:34 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=131</guid>
		<description><![CDATA[Similar to one of my first blog posts on building a basic application for Mac OS X using xcode 3.0, I am going to explain for beginning iPhone/iPod Touch developers how to build the most basic Cocoa Touch application using Interface Builder and an application delegate in xcode 3.1. This tutorial post is really to [...]]]></description>
			<content:encoded><![CDATA[<p>Similar to one of my first blog posts on building a basic application for Mac OS X using xcode 3.0, I am going to explain for beginning iPhone/iPod Touch developers how to build the most basic Cocoa Touch application using Interface Builder and an application delegate in xcode 3.1. This tutorial post is really to provide a quick how-to. I won&#8217;t go into any depth explaining why things are done the way they are done, but this should help you get up and running with your first application pretty quickly so that you too can clog the App Store with useless superfluous apps (kidding&#8230; just kidding).</p>

<p>If you are a visual learner, it may be helpful to you to instead watch a video presentation of this tutorial. I&#8217;ve posted it on the site, but you&#8217;ll have to click the link to see my <a href="http://www.cimgf.com/videos/iphonetutorial/">Cocoa Touch Video Tutorial</a>.
<span id="more-131"></span>
Understanding Cocoa programming is much simpler if you learn MVC, <strong>Model, View, Controller</strong>. You can probably step through code examples and figure some things out without learning MVC, but I wouldn&#8217;t recommend it. Go Google it and read up on it.</p>

<p>I will say as an introduction to MVC for those who are not familiar that it should probably be called <strong>(Model <--> Controller <--> View)</strong> or <strong>(View <--> Controller <--> Model)</strong> as the controller always sits between the other two. Your controller is either telling your model to update its data or it is telling the view to update its display. That&#8217;s the crux of the whole paradigm. The details run much deeper, but that&#8217;s how I will nutshell it for you.</li>
</ul></p>

<h1>Create Your Application</h1>

<p>Let&#8217;s get started. Create a Cocoa Application using the following steps:</p>

<ol>
<li>Select <strong>File > New Project&#8230;</strong>, under the <em>iPhone OS</em> templates choose <em>Window-Based Application</em> in the ensuing dialog. Click <strong>Choose&#8230;</strong></li>
<br />
<a href='http://www.cimgf.com/wp-content/uploads/2008/07/new-project.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/new-project-276x300.png" alt="iPhone Project Templates" title="iPhone Project Templates" width="276" height="300" class="alignleft size-medium wp-image-146" /></a>
<li>Enter &#8216;Basic iPhone App&#8217; as the project name. Click <strong>Save</strong></li>
</ol>

<p>You should see a project workspace like the following:</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/basic-iphone-app.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/basic-iphone-app-300x212.png" alt="Basic iPhone Application" title="Basic iPhone Application" width="300" height="212" class="alignleft size-medium wp-image-141" /></a></p>

<p>The next thing you should do is create a class to act as your controller or delegate.</p>

<h1>Delegate == Controller</h1>

<p>The words delegate and controller can be used synonymously. You&#8217;ll see later that we delegate the work of the different controls we create in Interface Builder to a delegate or controller class. In the iPhone template projects, this application delegate is created for you. Our app delegate has been named <em>Basic_iPhone_AppAppDelegate</em>.</p>

<p>In our app delegate class we need to add what Cocoa developers refer to as <em>outlets</em> and <em>actions</em>. I could spend an entire post explaining these two things in depth, but for the sake of brevity and walking you through the steps to build your first application, the definition will have to suffice.</p>

<blockquote>
Outlets represent controls in your user interface that can have some action performed upon them. Action are functions in your code that are connected to controls in your user interface such as a button or a drop down list. When connected to a button for instance, the action code will be run when the user clicks the button.</blockquote>

<p>In xcode, open your app delegate header file <em>Basic_iPhone_AppAppDelegate.h</em>. Add an outlet for the text field and the label below the window outlet as in the following snippet:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> Basic_iPhone_AppAppDelegate <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> &lt;UIApplicationDelegate&gt; <span style="color: #002200;">&#123;</span>
    IBOutlet UIWindow <span style="color: #002200;">*</span>window;
    IBOutlet UITextField <span style="color: #002200;">*</span>textField;
    IBOutlet UILabel <span style="color: #002200;">*</span>label;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>You will also want to add an action that will be performed when our button is clicked. Add that below the property for our window:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> Basic_iPhone_AppAppDelegate <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> &lt;UIApplicationDelegate&gt; <span style="color: #002200;">&#123;</span>
    IBOutlet UIWindow <span style="color: #002200;">*</span>window;
    IBOutlet UITextField <span style="color: #002200;">*</span>textField;
    IBOutlet UILabel <span style="color: #002200;">*</span>label;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIWindow <span style="color: #002200;">*</span>window;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>click<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;</pre></td></tr></table></div>


<p><li>Now switch over to the implementation file, <em>Basic_iPhone_AppAppDelegate.m</em>. Add the <em>click:</em> action below our <em>applicationDidFinishLaunching:</em> function:<br /></p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td 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>applicationDidFinishLaunching<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application <span style="color: #002200;">&#123;</span>	
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Override point for customization after app launch	</span>
    <span style="color: #002200;">&#91;</span>window makeKeyAndVisible<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>click<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
&nbsp;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p><br />
We will actually add some code to do something in the <em>click:</em> action handler, but first we need to hook it up to the user interface in Interface Builder.
</li><br />
</ol></p>

<h1>Interface Builder And Controller/Delegate Implementation</h1>

<p>Now that you&#8217;ve specified the outlets&#8211;a <em>UITextField</em> and a <em>UILabel</em> and an action called <em>click:</em>, you will see these items available for connecting to the UI in Interface builder. Let&#8217;s open Interface Builder and make the connections we need using the following steps:</p>

<ol>
<li>In your xcode workspace, expand the folder in the tree view called <strong>Resources</strong> and double click the file called &#8216;MainMenu.xib&#8217;. 
<blockquote><strong>Note:</strong>: A <em>.xib</em> is a <em>.nib</em> that uses XML for the internal data structure.</blockquote><br />
This will open the <em>xib</em> file in Interface Builder<br />
<li>Once Interface Builder loads, you will notice that there is an object representation of our app delegate in the <em>MainWindow.xib</em> window. This is the object you will use to create connections for your actions and outlets. 

<a href='http://www.cimgf.com/wp-content/uploads/2008/07/mainwindowxib.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/mainwindowxib-300x190.png" alt="MainWindow.xib" title="MainWindow.xib" width="300" height="190" class="alignnone size-medium wp-image-145" /></a>

</li>
</ol>

<h1>Design The User Interface</h1>

<p>Now you need to add the controls to the main window in Interface Builder and then we can connect the <em>action</em> and <em>outlet</em> accordingly. To finish the interface, complete the following steps:<br /></p>

<ol>
<li>Make sure that the Object Library is open by selecting Tools | Library from the menu in Interface Builder.<br />
<li>Drag a <em>TextField</em>, a <em>Label</em>, and a <em>Button</em> to the main window so that the user interface looks like the screenshot below:<br />

<a href='http://www.cimgf.com/wp-content/uploads/2008/07/ibwindow.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/ibwindow-191x300.png" alt="iPhone Application UI" title="iPhone Application UI" width="191" height="300" class="alignleft size-medium wp-image-143" /></a>

<li><strong>Control-Click</strong> and drag from the <em>Button</em> to your app delegate object in the &#8216;MainWindow.xib&#8217; window.<br />

<a href='http://www.cimgf.com/wp-content/uploads/2008/07/buttonconnect.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/buttonconnect-300x247.png" alt="Button Connection" title="Button Connection" width="300" height="247" class="alignleft size-medium wp-image-142" /></a>

<br />
A pop-up will display. Select <em>click:</em><br />
<br />
</li>
<li><strong>Control-Click</strong> the app delegate object and drag it to the text field in the main window.<br />

<a href='http://www.cimgf.com/wp-content/uploads/2008/07/textfieldconnect.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/textfieldconnect-300x248.png" alt="Textfield Connection" title="Textfield Connection" width="300" height="248" class="alignleft size-medium wp-image-147" /></a>

<br />
A pop-up will display. Select <em>textField</em><br />

</li>
<li><strong>Control-Click</strong> the app delegate object and drag it to the label in the main window.<br />

<a href='http://www.cimgf.com/wp-content/uploads/2008/07/labelconnect.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/labelconnect-300x244.png" alt="Label Connection" title="Label Connection" width="300" height="244" class="alignleft size-medium wp-image-144" /></a>

A pop-up will display. Select <em>label</em><br />
</li>
</ol>

<p>That&#8217;s it for Interface Builder. You can quit interface builder and return to xcode. We have one more piece of code to add and then our application will be finished.</p>

<h1>Finishing Up</h1>

<p>When the button is clicked, it will simply grab the text from the text field and place it into the label. That&#8217;s all the application does. Here&#8217;s the code you need. Just make your implementation of the <em>click:</em> action in the <em>Basic_iPhone_AppAppDelegate.m</em> file look like this:
<br /></p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>click<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>label setText<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>textField text<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Notice we are grabbing the text from the text field, and setting the text in our label with it. Now all you need to do is click &#8220;Build and Go&#8221;. When the application runs the <em>iPhone Simulator</em> will be started. You will see the application load. Type some text into the text field and click the <strong>Change</strong> button. You will see the label update with the text from the text field.</p>

<h1>Next Steps</h1>

<p>This tutorial has just scratched the surface. It&#8217;s is intended to get you going quickly. For a more in-depth path to gaining a deeper understanding of iPhone development, take a look at Apple&#8217;s, <a href="https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/chapter_1_section_1.html">Your First iPhone Application</a>. You will need to log in with your ADC account to see the article, but it is definitely worth while.</p>

<h1>Conclusion</h1>

<p>The limit with iPhone development is really just your imagination. It is an extremely fun platform to develop on and the resulting applications are very rewarding. Have fun with it and learn as much as you can. Just do me a favor and don&#8217;t clog the App Store with any more flashlight apps or tip calculators&#8230; Seriously ;-) . Until next time.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2008/10/basiciphoneapp.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br />Basic iPhone Application Demo Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
	</channel>
</rss>

