<?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>Thu, 15 Jul 2010 21:20:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<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>0</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[Objective-C]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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>8</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>16</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[Objective-C]]></category>
		<category><![CDATA[Version Control]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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>6</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[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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>4</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[Objective-C]]></category>
		<category><![CDATA[Undocumented]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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>4</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[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></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>45</slash:comments>
		</item>
	</channel>
</rss>
