<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Programming for iOS</title>
	<atom:link href="http://cupsofcocoa.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cupsofcocoa.com</link>
	<description>Thoughts and tutorials on the way</description>
	<lastBuildDate>Sat, 26 May 2012 20:24:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='cupsofcocoa.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/df688f9363a379e4a3ec72a74109f961?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Programming for iOS</title>
		<link>http://cupsofcocoa.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://cupsofcocoa.com/osd.xml" title="Programming for iOS" />
	<atom:link rel='hub' href='http://cupsofcocoa.com/?pushpress=hub'/>
		<item>
		<title>BlackBerry X: Initial Thoughts</title>
		<link>http://cupsofcocoa.com/2012/05/10/blackberry-x-initial-thoughts/</link>
		<comments>http://cupsofcocoa.com/2012/05/10/blackberry-x-initial-thoughts/#comments</comments>
		<pubDate>Thu, 10 May 2012 19:57:46 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[BlackBerry]]></category>
		<category><![CDATA[eye candy]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[RIM]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=553</guid>
		<description><![CDATA[BlackBerry X contains some nice new features and eye candy. I don't think it'll be enough to save the company and platform, but it is much better than the menu-driven version it will replace. <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=553&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Last week RIM released a preview of their new software, BlackBerry X. Normally my eyes would slide over the word &#8220;BlackBerry&#8221; like a greased weasel on skates, but something about the new release caught my attention. I had to do a triple take before I realized that, somehow, incredibly, BlackBerry X looked good. And the hardware they were using also looked good. I won&#8217;t really talk about the hardware—there&#8217;s not much to say. Ditching the physical keyboard frees them from the constraints of the plastic reality and the limited freedom of a hardware keyboard. The problem, though, is that RIM isn&#8217;t sure where it wants to go. They&#8217;ll still create a version with a physical keyboard—for the five people in the world who still like the physical keyboard. This also means that they can&#8217;t make any definitive call about having the keyboard or not. And at this point, RIM needs focus, rather than trying to appeal to everyone.</p>
<p>On to the software (because this is a site about software, after all). BlackBerry X features a pleasant amount of eye candy, but somehow still looks very professional. As a very satisfied iPhone user, the portions of the BlackBerry X interface seemed more polished somehow. The UI looks clean with a font suited for display. iOS uses Helvetica as its system font; while Helvetica looks timeless on paper, it is not as good on a display. The BlackBerry font is clean and modern, without being gimmicky or trendy. I noticed this in Android 4.0 (ICS), but I thought ICS had too much white-on-black. BlackBerry X keeps the clean look with more black- (and grey-) on-white. The UI elements look familiar but, again, clean and modern. Some of the icons are carried over from old BlackBerry, but other elements, including the rounded bars at the top of the screen, are decidedly iOS. Overall, however, I feel like BlackBerry X looks more professional—not button-down-and-suit-boring professional, but like the difference between metal and plastic. The iOS interface almost looks childish. I particularly like the ability to page through multiple screenfuls in a nav stack at the same time. It just feels more intuitive, and useful for those moments when you do a double-take (it&#8217;s happened to me more than you might think). Apple describes the nav controller as a deck of cards; you should be able to fan a deck of cards and peek at several. In the interest of simplicity iOS doesn&#8217;t allow this, but BlackBerry X seems to show that it works very well. It&#8217;s just not clear how exactly you&#8217;d invoke it. </p>
<p>The intelligent keyboard is the other major feature RIM has been touting. It uses &#8220;intelligent&#8221; algorithms to predict what you might be typing and with a flick up on the key of the software keyboard (another benefit to the software keyboard, and I suppose this feature won&#8217;t be available to the hardware keyboard model. Shame, really, that one of the major features won&#8217;t be available to a large portion of people who use BlackBerry (because they like the hardware keyboard)). The good thing is that it&#8217;s just one simple gesture—you&#8217;re flicking the word up to the text area. The negative is that it&#8217;s actually not that intuitive. When you&#8217;re typing fluently, there&#8217;s a sort of momentum in your fingers, in that it is often a lot easier to just keep typing than to use autocomplete or this new feature. Put another way, in the time it takes you to read the word suggestion, move your finger over and perform the flick gesture, you could probably have finished typing the word yourself. Only time will tell how well this feature works. I suspect a few people will use it religiously, and most will situationally appreciate it—rather like Siri on the iPhone 4S. </p>
<p>From what RIM&#8217;s released, I don&#8217;t think BlackBerry X will be enough to save the platform and company. But at least they&#8217;ll go out with a bang. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/553/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=553&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2012/05/10/blackberry-x-initial-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>
	</item>
		<item>
		<title>Extension: A Quartz Primer</title>
		<link>http://cupsofcocoa.com/2012/04/12/extension-a-quartz-primer/</link>
		<comments>http://cupsofcocoa.com/2012/04/12/extension-a-quartz-primer/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 00:27:51 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=548</guid>
		<description><![CDATA[Quartz is an incredible 2D drawing engine that allows you to draw complex graphics.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=548&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Because of the way my system is set up right now, I don&#8217;t have a version of Xcode that runs on my system. That&#8217;s part of the reason I haven&#8217;t posted anything in a while. I haven&#8217;t resolved the issue yet, but in the meantime, here is a primer on the Quartz 2D drawing system that allows you to do incredible things with graphics. </p>
<h1>Overview</h1>
<p>The iOS platform includes a powerful API that lets you directly draw content to the screen. The Core Graphics, or Quartz, framework was introduced in the early versions of Mac OS X, and was included in the iOS SDK. Quartz is a vector drawing API, which means that the drawing code is independent of the pixels on the screen. This is in contrast to usual image files, which has a finite number of pixels. The end result is that graphics drawn with Quartz will look especially sharp on Retina Displays, without resorting to additional resource files.</p>
<p>From Apple&#8217;s official documentation, &#8220;Quartz 2-D is an advanced, two-dimensional drawing engine available for iOS application development&#8230;. Quartz 2-D provides low- level, lightweight 2-D rendering with unmatched output fidelity regardless of display or printing device. Quartz 2-D is resolution- and device-independent; you don&#8217;t need to think about the final destination when you are using the Quartz 2-D&#8230;API for drawing.&#8221; We will talk about what this actually means throughout the course of this article.</p>
<div id="attachment_549" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2012/04/photo.jpg"><img src="http://cupsofcocoa.files.wordpress.com/2012/04/photo.jpg?w=600" alt="Stocks app screenshot—landscape" title="Stocks app"   class="size-full wp-image-549" /></a><p class="wp-caption-text">Stocks app: Custom drawing</p></div>
<p>Quartz is used to do a lot of custom drawing across iPhone apps and can distinguish apps and their custom interfaces. For example, the Stocks app uses to draw the graphs the reflect the stock price over a specific interview. It is not possible to ship the app with every possible graph already drawn out as a regular PNG image; the app has to create the graphics itself. It does this using the Quartz APIs.</p>
<p>The Quartz API is a C API, which means that you won&#8217;t be working with Objective-C method calls. All the code you write for Quartz will consist of C functions. Don&#8217;t be afraid of C though; the API is not any harder to use than the Objective-C stuff that you should be familiar with.</p>
<h1>How Quartz Works</h1>
<p>Two fundamental patterns govern most Quartz functions. Quartz, like many other rendering engines, is state-based. Generally, you set some values, such as color or line- width, and those same values continue to be used until you set other values. In addition, Quartz uses the artist&#8217;s model to layout contents. This simply means that content drawn first will appear underneath newer content; in other words, new content can obscure older content. Therefore, the order in which you draw things matters.</p>
<p>Most Quartz functions are relative to a specific context. A context is simply a virtual canvas which you can draw to. This could be the screen, a PDF, a bitmap image file, or a custom context. Most Quartz functions take a context as an argument, to know which context to draw to. In fact, this is how printing works: on-screen content is rendered to a printer context (often a PDF), and then send to the printer. This was a technological breakthrough when it was invented— to be able to use the same code to draw on-screen as to the printer.</p>
<p>There are three general types of functions in Quartz. You begin by drawing to the context. This creates an abstract, transparent representation in the context. At this point, there is a data structure in memory, but nothing is actually shown. You can then stroke and/or fill the content you&#8217;ve drawn to make it display on screen. This allows you to use Quartz as an underlying structure for more complex drawing, such as displaying text along a curve.</p>
<p>Quartz functionality should be immediately familiar to graphic designers. Nearly anything you can do with vector drawing programs, such as Adobe Illustrator, you can do with Quartz. You can, for example, set line width, line color, line endings (cap, butt, round), and various blend modes, to name a few of Quartz&#8217;s functions.</p>
<p>Drawing in a view begins in the drawRect: method, which is a method inherited from UIView. You put Quartz calls in <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">drawRect:</span>, or call drawing subroutines (additional functions that contain separate Quartz calls—splitting the drawing code across different things you might want to do). However, you should never call drawRect: directly; the system will call it as needed. If you want to force the system to redraw an area of the screen, you can call setNeedsDisplay on the view, and it will be redrawn according to the code in <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">drawRect:</span>.</p>
<h1>Drawing Basics</h1>
<p>Most drawing in Quartz begins with a graphics context. The simplest context is the &#8220;current&#8221; context, ostensibly the on-screen content. For iOS, you call UIGraphicsGetCurrentContext(), which returns an object of type CGContextRef. You should save this context in a local variable for all subsequent drawing calls:</p>
<p><pre class="brush: objc;">CGContextRef context = UIGraphicsGetCurrentContext();</pre></p>
<p>If you have additional functions that draw additional context (generally known as drawing subroutines), you should pass in the context as an argument to the function, then push the context on the graphics stack. You should also pop it when done. This allows you to keep a separate version of the context to work with in the subroutine, so changes you make, such as setting fill color or stroke style, don&#8217;t affect the state in any other function, including in <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">drawRect:</span> itself. In addition, the system automatically sets up the context each time drawRect: is called. No guarantee is made about the state of the context across multiple method calls; therefore, you should not save the context in a local variable. Simply call <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">UIGraphicsGetCurrentContext()</span> at the beginning of <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">drawRect:</span>.</p>
<p>Quartz, as you might imagine, is primarily based on x-y points. All points are positive (unless you do some custom mapping for whatever reason). On the iPhone, the point (0,0) is the top-left point of the view, which follows the convention of web design and makes sense in many cases. Quartz on the desktop uses the reverse—like in geometry textbooks, (0,0) is located at the bottom-left point. This means that, without any modification of points, Quartz code from the iPhone will appear upside-down on the desktop, and the opposite is true as well.</p>
<p>All drawing in Quartz begins with rectangles. They are represented by the CGRect structure, containing an origin point and a size; the former is comprised of an x- and y-value float, while the latter is composed of a width and height. You can then stroke or fill the rectangles directly. To draw other shapes, you can either define a free-form path, or start with a bounding rectangle. For example, you could draw a circle by starting with a square (which is a rectangle) without a stroke or fill, and then call the function <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">CGContextFillEllipseInRect()</span> if you want a filled circle, or <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">CGContextStrokeEllipseInRect()</span> if you want an outline.</p>
<p>But thinking outside the box, you are allowed to draw any shape you&#8217;d like in Quartz, ranging from triangles to intricate curves. You do this by defining paths. For example, to draw a triangle you could use something like this:</p>
<p><pre class="brush: objc;">CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath(context);
CGContextMoveToPoint(context, 100, 20);
CGContextAddLineToPoint(context, 150, 75);
CGContextAddLineToPoint(context, 50, 75);
CGContextClosePath(context); // Draws a straight line between first and last point</pre></p>
<p>This code segment defines a triangle in memory. However, for anything to appear on screen you&#8217;ll have to do a bit more setup.</p>
<p><pre class="brush: objc;">[[UIColor greenColor] setFill];
CGContextSetStrokeColor(context, [UIColor blackColor].CGColor);
CGContextDrawPath(context, kCGPathFillStroke);</pre></p>
<p>Quartz takes typedef’d CGColors, but the object-oriented UIColor works well with Quartz. Instances of UIColor have a setFill and setStroke method, which are used to set the stroke and fill in Quartz contexts. You can also use the Quartz function calls and get a CGColor from a UIColor instance using the CGColor property. Finally, there are a number of ways to fill and/or stroke paths. In this case, you pass in the context, and a preprocessor constant that tells Quartz to both fill and stroke.</p>
<p>Quartz constants generally begin with &#8216;k&#8217; and follow camel case conventions.</p>
<p>Quartz has functions to draw text and images, but UIKit provides classes that handle this for you. UILabel and UIImageView are much easier to work with than using Quartz to render text or images; unless you need exact control over the layout, consider using one of those classes instead.</p>
<h1>Drawing to a Close</h1>
<p>Quartz is an incredibly powerful 2D drawing engine. Over the coming weeks (when I can get my system set up again), we&#8217;ll explore code examples and explore ways to leverage Quartz to its maximum potential.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/548/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=548&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2012/04/12/extension-a-quartz-primer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/04/photo.jpg" medium="image">
			<media:title type="html">Stocks app</media:title>
		</media:content>
	</item>
		<item>
		<title>The Jungle, Part 6: Navigation Controllers and Stacks</title>
		<link>http://cupsofcocoa.com/2012/02/25/the-jungle-part-6-navigation-controllers-and-stacks/</link>
		<comments>http://cupsofcocoa.com/2012/02/25/the-jungle-part-6-navigation-controllers-and-stacks/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 21:14:12 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[UINavigationController]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=544</guid>
		<description><![CDATA[UINavigationController handles a stack of views, which are presented in a pre-determined order. You push a view to make it visible, and pop it off to go back.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=544&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Navigation controllers are a cornerstone of iOS—they allow you to present a lot more information than you could fit on one screen, in a hierarchical format that is intuitive to the user. What does that mean? Think of it as a deck of cards (to use an oft-quoted metaphor). You have a stack of views with a &#8220;vertical&#8221; order. You can only see the top view, but there can be views underneath, and you can put views on top. And nav controllers are everywhere, so users are already familiar with it.</p>
<p>A UINavigationController handles the nav stack, as well as the corresponding animations. All you have to do is push and pop views controllers, if necessary. You will usually have to push view controllers on the stack, but by default, the back arrow in the upper-left will pop the controller automatically. You do have the ability to pop any number of existing view controllers programmatically if you need to—for example, in an app with a tab bar, tapping on a tab will take you to the root controller (first controller), which means that if you&#8217;re already in that tab, it&#8217;ll programmatically pop to the root controller.</p>
<p>Tab bar controllers and nav controllers are often seen together. In these situations you have some choices as to the design of the app. If each tab is displaying different content, you may want each tab to contain its own nav controller as the tab&#8217;s assigned view controller. Alternatively, if your different tabs just show a different sorting order or a different view on the same data, you might want to have the tab bar exist independently of the nav controller, and simply refresh the nav controller&#8217;s view when a different tab is selected. It is a bad idea to have each nav controller own its tab bar; you should not change your tab bar across different views of your app. </p>
<p>We&#8217;ll add navigation to our demo app, so open up the app that we&#8217;ve been working on not too long ago. Create a new UIViewController and call it CustomDrawingViewController (yes, next post we&#8217;ll look at doing some custom drawing using Quartz/Core Graphics—same thing). We&#8217;ll add a property that will allow you to set the title of the view before you push it on. Declare and synthesize a property of type NSString called viewTitle. Assign that property as the title in viewDidLoad:</p>
<p><pre class="brush: objc;">
if (!self.viewTitle)
		self.title = @&quot;Custom Drawing&quot;;
	else
		self.title = self.viewTitle;</pre></p>
<p>If the property did not get set, it&#8217;ll use the generic &#8220;Custom Drawing&#8221; title; otherwise it uses whatever was set. Now go to GraphicsTableViewController.m, where we&#8217;ll push the view controller. We do that in tableView:didSelectRowAtIndexPath:. Replace the deselect method with the following:</p>
<p><pre class="brush: objc;">
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    CustomDrawingViewController *drawingVC = [[CustomDrawingViewController alloc] init];
	drawingVC.viewTitle = [[tableView cellForRowAtIndexPath:indexPath] textLabel].text;
	[self.navigationController pushViewController:drawingVC animated:YES];
}</pre><br />
Import CustomDrawingViewController.h. In this code, we create an instance of our new view controller. We set the title to be the text of the table view cell that was just tapped. Finally, we push on the new view controller. Note the call to self.navigationController. Nav controllers are so common in iOS that UIViewController contains a property to a parent navigation controller. If the view controller is not a child of a nav controller, then the property will be nil. Also note the animated parameter in the last method. You always want to animate the change if it&#8217;s going to be visible. Put another way, the only time you don&#8217;t want to animate is if you&#8217;re loading the first view of a stack, because the animation won&#8217;t be seen anyway. </p>
<p>Build and run, and select the Graphics Demo tab. Tap on any cell, and you&#8217;ll see an animation to a blank screen. </p>
<div id="attachment_545" class="wp-caption alignleft" style="width: 406px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-25-at-4-08-31-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-25-at-4-08-31-pm.png?w=600" alt="Nav Controller" title="Nav Controller"   class="size-full wp-image-545" /></a><p class="wp-caption-text">Pushing on a new view</p></div>
<p>There will also be a back arrow in the upper left. Tap on that to go back.</p>
<p>Download the current version <a href="//api.cld.me/102T2M0x321R0U1E3x0p/download/SDK%20Demo%20v6.zip">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/544/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=544&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2012/02/25/the-jungle-part-6-navigation-controllers-and-stacks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-25-at-4-08-31-pm.png" medium="image">
			<media:title type="html">Nav Controller</media:title>
		</media:content>
	</item>
		<item>
		<title>Extension: Rotation</title>
		<link>http://cupsofcocoa.com/2012/02/05/extension-rotation/</link>
		<comments>http://cupsofcocoa.com/2012/02/05/extension-rotation/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 21:06:37 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Series]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[IPhone]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[UIKit]]></category>
		<category><![CDATA[UIView]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=524</guid>
		<description><![CDATA[Not all apps support or need rotation, but it can add an extra dimension. There's an easy way to do it, but it might not be perfect. For more complex views, you can manually perform the rotation.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=524&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this post we&#8217;ll talk about how to handle rotating a UI. We&#8217;ll start by using existing constructs to allow our views to support rotation, and then discuss complications and their solutions. Start with a new Single View Application and call it AutoRotate. As usual, I&#8217;ll be using <a href="http://cupsofcocoa.com/2011/11/27/the-jungle-part-4-automatic-reference-counting/">ARC</a>. Open the main view controller&#8217;s implementation. </p>
<h1>Enabling Rotation in Code</h1>
<p>First, we have to tell the system that the view controller supports rotation and that it should rotate to a specific orientation. We do this by implementing an existing method on UIViewController:</p>
<p><pre class="brush: objc;">
#pragma mark - Rotation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
	return (toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}</pre></p>
<p>The method might already exist in the file, provided by the template. In that case, simply change the method contents. </p>
<p>In this method, we&#8217;re returning a boolean value that tells the system whether to rotate to a specific orientation. We return YES for all supported orientations. Note though that we are not supporting UIInterfaceOrientationPortraitUpsideDown. Apple&#8217;s guidelines state that the upside-down orientation should not be supported unless necessary, because might end up being confused about which way is up, an important feature of phones. Of course, this distinction isn&#8217;t made on the iPad, and Apple strongly recommends to support all four orientations on iPad. But for now, we&#8217;ll support all except upside-down. </p>
<p>Now we&#8217;ll build the interface and implement the actual rotation logic—open the XIB. Design an interface like this one. It doesn&#8217;t matter exactly what you use, but keep it simple with some of the basic UI elements. The bar at the bottom is a UIToolbar. I put three UIBarButtonItems on it and two Flexible Spacers in between. </p>
<div id="attachment_526" class="wp-caption alignright" style="width: 366px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-11-45-53-am.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-11-45-53-am.png?w=600" alt="Initial View" title="Initial View"   class="size-full wp-image-526" /></a><p class="wp-caption-text">Initial View</p></div>
<p>We don&#8217;t need to hook up any of the elements, because we&#8217;re just concerned with rotating the view. Build and run the app. </p>
<div id="attachment_527" class="wp-caption aligncenter" style="width: 406px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-11-59-44-am.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-11-59-44-am.png?w=600" alt="Initial View in Simulator" title="Initial View in Simulator"   class="size-full wp-image-527" /></a><p class="wp-caption-text">Initial View in Simulator</p></div>
<p>You can rotate the iPhone Simulator by 90 degrees at a time. Go to the Hardware menu, and then select Rotate Left or Rotate Right. You can also use Command-LeftArrow or Command-RightArrow. The rotation will be accompanied by a corresponding animation, and you&#8217;re left with a view that look like this:</p>
<div id="attachment_528" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-14-13-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-14-13-pm.png?w=600" alt="Mangled Rotation" title="Mangled Rotation"   class="size-full wp-image-528" /></a><p class="wp-caption-text">Mangled Rotation</p></div>
<p>While the background rotated (along with the bottom toolbar, which is handled by the system, the rest of the view didn&#8217;t change. We can fix that with a few different ways.</p>
<h1>Struts and Springs</h1>
<p>Struts and springs are a simple IB construct that gives you a few options to stretch and position views. Select the &#8220;1&#8243; button and go to the Size Inspector (the one with the Ruler icon). You&#8217;ll see a section called Autosizing. If you mouse over the Example area to the right, it&#8217;ll animate to show you the changes. </p>
<div id="attachment_529" class="wp-caption aligncenter" style="width: 269px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-29-11-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-29-11-pm.png?w=600" alt="Autosizing UI" title="Autosizing UI"   class="size-full wp-image-529" /></a><p class="wp-caption-text">Autosizing UI</p></div>
<p>The autosizing area is where you make the changes. You&#8217;ll see a square with I-beams (struts) on the outside and double arrows (springs) on the inside. The I-beams on the outside acts as &#8220;anchors&#8221; to the sides of the containing view. The arrows on the inside tell the subview to expand with the containing view. Behavioral conditions:</p>
<ul>
<li>If all the I-beams are enabled, the subview will stay the same size and anchored near (0,0) in the containing view. On the iPhone, that would be the top-left corner.</li>
<li>If no I-beams or double arrows are enabled, the subview will stay in the same size in the center of the containing view.</li>
<li>If all the double arrows are enabled but no I-beams, the subview will expand proportionally to the containing view.</li>
<li>If all the double arrows and I-beams are enabled, the view will expand with the subview, keeping the same distance around all the edges.</li>
</ul>
<p>You can see all of this happening in the Example. </p>
<p>We can use these struts and springs to position some of the UI. All the buttons and the label should have both springs enabled. The progress view and slider should have the horizontal spring enabled. Button 1 should have the top and left struts enabled; button 2 should have top and right. Button 3 should have just left; button 4 should have just right. The label should have no struts enabled. </p>
<p>The progress view should have just the left strut; the slider just the right strut. The textview at the bottom should have both springs, the bottom, and left and right struts enabled. </p>
<p>Build and run again, and we see something like this:</p>
<div id="attachment_530" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-53-07-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-53-07-pm.png?w=600" alt="Struts &amp; Springs UI" title="Struts &amp; Springs UI"   class="size-full wp-image-530" /></a><p class="wp-caption-text">Struts &amp; Springs UI</p></div>
<p>It&#8217;s almost perfect. Springs and struts give you some basic flexibility—it moved our buttons and label nicely—but for more complex situations, like the lower part of our view, we need something more robust. </p>
<h1>Swapping Views</h1>
<p>Swapping views as necessary gives you the flexibility to structure your views any way you want using the convenience of Interface Builder. Begin by adding two outlets to the view controller&#8217;s header:</p>
<p><pre class="brush: objc;">
@property (strong, nonatomic) IBOutlet UIView *portraitView;
@property (strong, nonatomic) IBOutlet UIView *landscapeView;
</pre></p>
<p>Synthesize the properties and go over to the XIB. Drag out a new view and go to the Attributes Inspector. Under Orientation in Simulated Metrics, select &#8220;Landscape&#8221;. Build a view similar to this:</p>
<div id="attachment_525" class="wp-caption aligncenter" style="width: 528px"><a href="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-3-20-28-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-3-20-28-pm.png?w=600" alt="Manual Landscape View" title="Manual Landscape View"   class="size-full wp-image-525" /></a><p class="wp-caption-text">Manual Landscape View</p></div>
<p>Connect the new view as landscapeView, and the old view as portraitView. Go to the implementation file, where we will handle the swap. Add the following code to the bottom of the file, before the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">@end</span>:</p>
<p><pre class="brush: objc;">
#define degreesToRadians(x) (M_PI * (x) / 180.0)
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
	if (toInterfaceOrientation == UIDeviceOrientationPortrait) {
		self.view = self.portraitView;
		self.view.transform = CGAffineTransformIdentity;
		self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0)); 
		self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
	}
	else if (toInterfaceOrientation == UIDeviceOrientationLandscapeRight) {
		self.view = self.landscapeView;
		self.view.transform = CGAffineTransformIdentity; 
		self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); 
		self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
	}
	else if (toInterfaceOrientation == UIDeviceOrientationLandscapeLeft) {
		self.view = self.landscapeView;
		self.view.transform = CGAffineTransformIdentity; 
		self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); 
		self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
	}
	else
		return;
}</pre></p>
<p>We start with a pre-processor macro that converts degrees to radians. iOS uses radians in its graphics work, but it&#8217;s easier for us people to think in degrees. Note that in this case, we will have to do some custom graphics work, because we will have to transform the view to match the rotation. </p>
<p>Inside the delegate method, we check for the corresponding orientation and swap the view in the first line of each condition. Then we reset the view&#8217;s transformation. We&#8217;ll cover transformations in a future post. We use a provided function to make a rotation transformation and apply it to the view. We also change the size of the view to fit the screen. All of these changes happen in the <em>will</em> method, so they are complete before the actual rotation happen, and the correct view will be displayed in time. Note that animating all aspects of the transition would require additional code, which is beyond the scope of this post. </p>
<h1>Rotating Tips</h1>
<p>On the iPhone, not all apps support all orientations, or even rotation at all. On iPad, apps should support as many orientations as possible—at least both variants one orientation; preferably all four orientations. </p>
<p>Note that landscape and portrait views don&#8217;t necessarily have to present the same information, or even the same appearance. The Music app on the iPhone displays a UIKit-based tab bar and table interface in portrait view, but a custom coverflow interface in landscape. </p>
<p>If you&#8217;re doing some custom views/drawing, make sure the view animates when you rotate, especially if you&#8217;re displaying content such a grid of icons or text. Otherwise, it is a very disorientating experience for the user and might discourage use of your app. </p>
<p>Finally, make sure there is some meaningful change when the user rotates. If you&#8217;re just stretching the UI, consider whether it makes sense to rotate, or if rotation is worth the effort. If you have text input, the larger keyboard might be worth it—but you also loose a large portion of the rest of the content. Otherwise, rotating might not be necessary. </p>
<p>Download AutoRotate <a href="http://api.cld.me/1M1a2f2K2v1l0x133P0t/download/AutoRotate.zip">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/524/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=524&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2012/02/05/extension-rotation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-11-45-53-am.png" medium="image">
			<media:title type="html">Initial View</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-11-59-44-am.png" medium="image">
			<media:title type="html">Initial View in Simulator</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-14-13-pm.png" medium="image">
			<media:title type="html">Mangled Rotation</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-29-11-pm.png" medium="image">
			<media:title type="html">Autosizing UI</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-12-53-07-pm.png" medium="image">
			<media:title type="html">Struts &#38; Springs UI</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/02/screen-shot-2012-02-05-at-3-20-28-pm.png" medium="image">
			<media:title type="html">Manual Landscape View</media:title>
		</media:content>
	</item>
		<item>
		<title>Extension: Advanced Tables</title>
		<link>http://cupsofcocoa.com/2012/01/16/extension-advanced-tables/</link>
		<comments>http://cupsofcocoa.com/2012/01/16/extension-advanced-tables/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 00:32:15 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Series]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[automatic reference]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[UITableView]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=516</guid>
		<description><![CDATA[iOS tables have a lot more to offer. In this post we explore some of the more common features.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=516&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this post we&#8217;re going to take a step away from our existing project and look at other things <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">UITableView</span> will allow us to do. We&#8217;ll load in data from a plist, add some more elements to our table view, including images, subtexts, and allowing editing. These features allow us and the user to customize table views beyond the default appearance. Table views are a very important part of the iOS SDK and are found in many apps; fortunately, they are easy to customize—you can even create your own cells in anyway you&#8217;d like!</p>
<p>Open Xcode and create a new Single View application. Call it &#8220;AdvancedTables&#8221;, set the class prefix to &#8220;AT&#8221;, Device Family to iPhone, and Use Automatic Reference Counting. Save the project somewhere and create it. </p>
<p>Next, <a href="http://api.cld.me/2M3B1Q3Z060v0u2Y3032/download/Cities.plist">click here</a> to download a file which contains a list of 51 cities and their population. The file is a basic XML-based <em>plist</em>, which is a file type used throughout iOS to store simple data structures like this. Add the file into the Xcode project.</p>
<h1>Setting up the View Controller</h1>
<p>Open ATViewController.h and have it adopt <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">UITableViewDelegate</span> and <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">UITableViewDataSource</span>. In ATViewController.xib, drag out a Table View from the Library and place it inside the existing view. Control-Drag from the table back to File&#8217;s Owner, connecting the table&#8217;s data source and delegate outlets. </p>
<p>Next, go to ATViewController.h. Create two strong properties of type NSMutableArray; call them names and populations. In the .m file, synthesize them. We&#8217;ll load in data from the plist in the viewDidLoad method:</p>
<p><pre class="brush: objc;">
- (void)viewDidLoad {
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
	NSString *filePath = [[NSBundle mainBundle] pathForResource:@&quot;Cities&quot; ofType:@&quot;plist&quot;];
	NSData *data = [NSData dataWithContentsOfFile:filePath];
	NSPropertyListFormat format;
	NSString *error;
	id fileContents = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:&amp;format errorDescription:&amp;error];
	self.populations = [[fileContents objectForKey:@&quot;City Population&quot;] mutableCopy];
	self.names = [[fileContents objectForKey:@&quot;City Names&quot;] mutableCopy];
}
</pre></p>
<p>Notice that we don&#8217;t do any sort of checking on the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">fileContents</span> result. It would may seem like a good idea to at least check if the dictionary had the two keys; if it only had one, the app would crash when trying to access one or both of them. However, this is a special design consideration. The data source is the driving force of the entire app; it wouldn&#8217;t make much sense if some of this data doesn&#8217;t exist. We don&#8217;t really want the app to continue if the data isn&#8217;t valid, so letting it crash might be a good idea in this case.</p>
<p>Next, we implement the data source methods like we did in the last post. Our table will only one section; with a more robust data source such as Core Data, it becomes much easier to implement multiple sections and an index down the side like you&#8217;d see in the Music app. For now though, we&#8217;ll settle for one section. The number of rows will be determined by the number of elements in either one of the data arrays, as they should correspond—and they do!</p>
<p><pre class="brush: objc;">
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	return [self.names count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	static NSString *cellID = @&quot;CellID&quot;;
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
	if (!cell) {		// Create new cell
		cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
		cell.showsReorderControl = YES;
	}
	cell.textLabel.text = [self.names objectAtIndex:indexPath.row];
	cell.detailTextLabel.text = [NSString stringWithFormat:@&quot;Population: %@&quot;, [self.populations objectAtIndex:indexPath.row]];
	cell.imageView.image = [UIImage imageNamed:@&quot;CaliforniaIcon.png&quot;];
	cell.imageView.highlightedImage = [UIImage imageNamed:@&quot;CaliforniaIconPressed.png&quot;];
	return cell;
}
</pre></p>
<p>Notably here, we create a cell with a different style, one with a subtitle. The iOS SDK comes with four styles, shown below (click for larger version):</p>
<div id="attachment_517" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2012/01/ios-table-view-cell-styles.png"><img src="http://cupsofcocoa.files.wordpress.com/2012/01/ios-table-view-cell-styles.png?w=600" alt="iOS Table View Cell Styles" title="iOS Table View Cell Styles"   class="size-full wp-image-517" /></a><p class="wp-caption-text">iOS Table View Cell Styles</p></div>
<p>The default style doesn&#8217;t contain any detail text; nothing will happen if you set the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">detailTextLabel</span> property. </p>
<p>The <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">showsReorderControl</span> property is a boolean; if true, it will display a reordering control that appears in editing  mode. We&#8217;ll get into that in a little bit.</p>
<h1>Adding an Image to Cells</h1>
<p>If you want to add an image to the left of the cell (as with album art in the Music app, or video previews in the YouTube app), it takes very little work. <a href="http://api.cld.me/0L3H3P1g1f2f2F3M1I1L/download/Icons.zip">Download the icons</a> and add the following lines within the if (!cell) block:</p>
<p><pre class="brush: objc;">
cell.imageView.image = [UIImage imageNamed:@&quot;CaliforniaIcon.png&quot;];
cell.imageView.highlightedImage = [UIImage imageNamed:@&quot;CaliforniaIconPressed.png&quot;];
</pre></p>
<p>The <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">image</span> property is what gets displayed normally; the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">highlightedImage</span> is swapped in if the cell is highlighted. </p>
<p>If you want the image anywhere else in the cell, you&#8217;ll have to create your own cells, which will be a topic for another post—there&#8217;s a lot involved!</p>
<h1>Editing Table Views</h1>
<p>First we&#8217;ll need some UI to enable editing. Go into the XIB, lower the top margin of the table view, and drag out a normal Navigation Bar and place it at the top of the view, filling the gap. You can have a navigation bar without a nav controller; in that case, it just becomes an &#8220;anchor&#8221; of sorts for a few commands. You use nav bars at the top of the screen and toolbars at the bottom. Drag out a Bar Button Item and place it on the left of the nav bar; a &#8220;well&#8221; will appear as you drag over the location. In the Attributes Inspector, set the Title to &#8220;Edit&#8221;. Connect the button to a new property called <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">editingToggle</span>. In addition, create an outlet for the table view; call it tableView. Wire it up. </p>
<p>Create a new method called toggleEdit and wire it up to the button. First, we&#8217;ll set the table&#8217;s editing mode to whatever it&#8217;s currently <em>not</em>—if it&#8217;s not in editing, make it enter editing mode and vice versa. Then we&#8217;ll adjust the button to reflect this change in state. In iOS, the Done button has a different tint; we can use a system-defined parameter rather than having to approximate it with our own.</p>
<p><pre class="brush: objc;">
- (IBAction)toggleEdit:(id)sender {
	[self.mainTable setEditing:!self.mainTable.isEditing animated:YES];
	if (self.mainTable.isEditing) {
		[self.editingToggle setStyle:UIBarButtonItemStyleDone];
		[self.editingToggle setTitle:@&quot;Done&quot;];
	}
	else {
		[self.editingToggle setStyle:UIBarButtonItemStyleBordered];
		[self.editingToggle setTitle:@&quot;Edit&quot;];
	}
}
</pre></p>
<p>Next we implement a few data source methods to allow editing, then to handle the edits.</p>
<p><pre class="brush: objc;">
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
	return YES;
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
	return YES;
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
	NSUInteger fromRow = [fromIndexPath row];
	NSUInteger toRow = [toIndexPath row];
	id name = [self.names objectAtIndex:fromRow];
	id pop = [self.populations objectAtIndex:fromRow];
	[self.names removeObjectAtIndex:fromRow];
	[self.populations removeObjectAtIndex:fromRow];
	[self.names insertObject:name atIndex:toRow];
	[self.populations insertObject:pop atIndex:toRow];
}

- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
	NSUInteger row = [indexPath row];
	[self.names removeObjectAtIndex:row];
	[self.populations removeObjectAtIndex:row];
	[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
</pre></p>
<p>The first two methods tell the table that all the rows can be edited (in this case, deletion is allowed; the alternative is None or Insertion), and that they can be moved. Then we declare the methods that handle the move or delete (in the latter case, it falls under the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">commitEditingStyle:</span> method). In those methods, we remove (and insert) objects from our backing arrays as necessary. </p>
<p>These edits will remain until the memory is cleared (when the app quits). We&#8217;ll look at persistence—saving these changes back to the file—in a later extension.</p>
<h1>Other Actions</h1>
<p>The <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">UITableViewDelegate</span> declares some methods to support some other actions, including accessory views (views on the side of the cell, which you can wire up to trigger additional actions). Now, we&#8217;ll handle the selection, and allow you to put a check mark next to the cell that the user selects. </p>
<p>First, we&#8217;ll need to create a new property of type <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">NSIndexPath</span> that will hold the current selection. </p>
<p><pre class="brush: objc;">
@property (strong, nonatomic) NSIndexPath *lastIndexPath;
</pre></p>
<p>Next, we need to do some checks in the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">cellForRow…</span> method—because the method will recycle cells as you scroll, we don&#8217;t want the checkmarks to get recycled as well. We check to see if a selection has been made, and if the rows are the same. If they are, then we display the checkmark (this is useful when you scroll back to your selection). Else, we display no checkmark (this is useful if you scroll down or up past your existing selection). </p>
<p>We handle the selection like this:</p>
<p><pre class="brush: objc;">
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	NSUInteger row = indexPath.row;
	NSUInteger oldRow = lastIndexPath.row;
	if (oldRow != row) {
		UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath]; 
		newCell.accessoryType = UITableViewCellAccessoryCheckmark;
		UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
		oldCell.accessoryType = UITableViewCellAccessoryNone;
		lastIndexPath = indexPath;
	}
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
</pre></p>
<p>If the selections are different, we put a checkmark on the new cell and put nothing on the old cell. If they&#8217;re the same, nothing changes. In either case, we deselect the cell to prevent it from being highlighted. Build and run, and you can see the checkmark appearing as you click on each cell.</p>
<h2>Row Heights</h2>
<p>You can change the height of one or more rows using a simple delegate method:</p>
<p><pre class="brush: objc;">
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
	return 88;
}
</pre></p>
<p>The default height is 44; this method would make the cells twice as high.</p>
<h2>Indenting Rows</h2>
<p>You can control the indent of each row with a delegate method:</p>
<p><pre class="brush: objc;">
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
	return indexPath.row;
}
</pre></p>
<p>This example would create a cascade of cells being indented further with each row. Going beyond a level of 5 or 6 looks really weird, so don&#8217;t go too far.</p>
<p>That&#8217;s the primary abilities that standard table views can offer. The data source and delegate protocols declare a few other features; we&#8217;ll touch upon some of them including sections and the index when we start working with files and persistence.</p>
<p>Download the project <a href="http://api.cld.me/3p2I3J3z413j2I2F3p1d/download/AdvancedTables.zip">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/516/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=516&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2012/01/16/extension-advanced-tables/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2012/01/ios-table-view-cell-styles.png" medium="image">
			<media:title type="html">iOS Table View Cell Styles</media:title>
		</media:content>
	</item>
		<item>
		<title>The Jungle, Part 5: Table Views and Nav Controllers</title>
		<link>http://cupsofcocoa.com/2011/12/17/the-jungle-part-5-table-views-and-nav-controllers/</link>
		<comments>http://cupsofcocoa.com/2011/12/17/the-jungle-part-5-table-views-and-nav-controllers/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 02:51:54 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Series]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[UINavigationController]]></category>
		<category><![CDATA[UITableViewController]]></category>
		<category><![CDATA[way of thinking]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=511</guid>
		<description><![CDATA[Tabe views and nav controllers work hand-in-hand and form a fundamental part of the iOS SDK. <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=511&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Table View Controllers and navigation controllers are two of the most commonly used controllers in the iOS SDK. They require a tweaked way of thinking, but they become much easier to use. We&#8217;ll begin with table views. </p>
<h1>UITableViewControllers</h1>
<p>There exists a stand-alone UITableView, but in many cases UITableViewController simplifies usage of the table view. It handles loading table views from XIBs, reloading data, editing, and implements the data source and delegate protocols. Table views display a list of information, potentially millions of objects long, because of a a clever optimization in the data source methods; usually table view cells can be selected and trigger an action or navigate to another view in a navigation hierarchy. This post will build a table view embedded in a navigation controller, which will allow us to build subviews in a later post. </p>
<h2>Data Sources and Delegates</h2>
<p>Many UIViews rely on data source protocols to load data. These protocols often ask your controller about sections in your data, and the objects to be displayed within each section. The delegate protocols usually handle selections and editing. The concept can be a bit difficult to grasp at first, but it is one of distinguishing factors of the iOS SDK and really simply your program. </p>
<h2>Creating the controller</h2>
<p>Open up our application in Xcode. Create a New File. Under Cocoa Touch, select UIViewController subclass. Click Next, and call it GraphicsTableViewController and underneath make it a subclass of UITableViewController. Leave the XIB checkbox checked, and create the file. In the XIB, select the table and open the Attributes Inspector. Notice that you can&#8217;t edit the data in the table view from IB; it contains a list of California cities. In the Attributes, the one setting that you will often change is the &#8220;Style&#8221; drop-down; your options are &#8220;Plain&#8221; or &#8220;Grouped.&#8221; Change this to &#8220;Grouped.&#8221;</p>
<div id="attachment_512" class="wp-caption aligncenter" style="width: 373px"><a href="http://cupsofcocoa.files.wordpress.com/2011/12/screen-shot-2011-12-17-at-6-44-05-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/12/screen-shot-2011-12-17-at-6-44-05-pm.png?w=600" alt="Group Table View Appearance" title="Group Table View Appearance"   class="size-full wp-image-512" /></a><p class="wp-caption-text">Group Table View Appearance</p></div>
<p>Save, and go to GraphicsTableViewController.h. Add the following property:</p>
<p><pre class="brush: objc;">
@property (strong, nonatomic) NSDictionary *tableViewData;
</pre></p>
<p>Go to the .m file and synthesize this property. In viewDidLoad, populate this dictionary:</p>
<p><pre class="brush: objc;">
self.title = @&quot;Graphics Demo&quot;;
NSArray *section1 = [NSArray arrayWithObjects:@&quot;Straight Lines&quot;, @&quot;Curves&quot;, @&quot;Shapes&quot;, nil];
	NSArray *section2 = [NSArray arrayWithObjects:@&quot;Solid Fills&quot;, @&quot;Gradient Fills&quot;, @&quot;Image &amp; Pattern Fills&quot;, nil];
	NSArray *section3 = [NSArray arrayWithObjects:@&quot;Simple Animations&quot;, @&quot;Bounce&quot;, @&quot;Other Options&quot;, nil];
	self.tableViewData = [NSDictionary dictionaryWithObjectsAndKeys:section1, @&quot;Section1&quot;, section2, @&quot;Section2&quot;, section3, @&quot;Section3&quot;, nil];
</pre></p>
<p>First, we have to set the view controller&#8217;s title so it will display when we create our nav controller. Setting the nav controller&#8217;s title does nothing; it uses the title of the visible view controller. Having established the data that we&#8217;re going to put into our table view, scroll down to</p>
<p><pre class="brush: objc;">
#pragma mark - Table view data source
</pre></p>
<p>A quick way is to use the jump list, where the section will be delineated. </p>
<div id="attachment_513" class="wp-caption aligncenter" style="width: 372px"><a href="http://cupsofcocoa.files.wordpress.com/2011/12/screen-shot-2011-12-17-at-7-33-49-pm.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/12/screen-shot-2011-12-17-at-7-33-49-pm.png?w=600" alt="Xcode Jump Lists" title="Xcode Jump Lists"   class="size-full wp-image-513" /></a><p class="wp-caption-text">Xcode Jump List</p></div>
<p>In numberOfSectionsInTableView:, return the count of objects in our dictionary and remove the warning:</p>
<p><pre class="brush: objc;">
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return [self.tableViewData count];
}
</pre></p>
<p>Here, the data source method is asking for the number of sections in our table, which controls how it gets displayed (where the section headings/breaks are). We return the count (of objects with keys) in our dictionary. Do something similar for numberOfSectionsInTableView:</p>
<p><pre class="brush: objc;">
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	id sectionInfo = [self.tableViewData objectForKey:[NSString stringWithFormat:@&quot;Section%d&quot;, section + 1]];
	return [(NSArray *)sectionInfo count];
}
</pre></p>
<p>This method asks for the number of elements in a particular section. UITableViews&#8217; sections (and rows) are zero-indexed. We get the corresponding section by incrementing the section by 1, and then return the number of elements in that section. </p>
<p>The next method is where it gets interesting. tableView:cellForRowAtIndexPath: is where you configure each cell in your table; obviously you won&#8217;t be actually configuring <em>every</em> single cell, that&#8217;s the job of the computer. </p>
<p><pre class="brush: objc;">
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @&quot;Cell&quot;;
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
		// Common to all cells
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    
    // Configure individual cells
	id section = [self.tableViewData objectForKey:[NSString stringWithFormat:@&quot;Section%d&quot;, indexPath.section + 1]];
	NSString *rowLabel = [section objectAtIndex:indexPath.row];
	cell.textLabel.text = rowLabel;
    
    return cell;
}
</pre></p>
<p>A lot of the code in this method has already been written out. First, it creates an object—a string in this case—that is an identifier. The next line is where the optimization comes in. Rather than creating new table cells all the time as you scroll (because creating objects is an &#8220;expensive&#8221; process), the table view <em>dequeues</em> cells as they scroll off-screen. At their default size, about nine cells fit on-screen at a time, so only nine need to be kept in memory. As they get scrolled off-screen, the properties&#8217; values are changed, and it is put back into use. This means that you can have a table with millions of cells, but only nine or fewer have to exist in memory. The code checks to see that a cell exists (for the first few to be created, or if there is an error, there won&#8217;t be any cells available to dequeue) and if it doesn&#8217;t a new cell is created. Inside the if statement is where you configure settings that you want to be common to all (or a large number of) cells, perhaps including color and style, or some text that you want on all the cells. After creating the cell, we get our section and pull out the label for the row. We then access the textLabel property of the cell and set its text property to the text we just got. We then return the cell.</p>
<p>We need to add one more method to the controller to let it display section headings. </p>
<p><pre class="brush: objc;">
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
	switch (section) {
		case 0:
			return @&quot;Lines &amp; Shapes&quot;;
			break;
		case 1:
			return @&quot;Images &amp; Fills&quot;;
			break;
		case 2:
			return @&quot;Animations&quot;;
			break;
		default:
			return nil;
			break;
	}
}
</pre></p>
<p>This method simply goes through the possible values for section and returns a title accordingly. </p>
<p>That is all you need to get data in a table view. In fact, a simpler table view would not have sections, and could be done using a single array. At this point, however, we have not handled selection. Scroll down a bit further, until you find the method tableView:didSelectRowAtIndexPath:. In the next post, we&#8217;ll create a view controller that will be displayed when you select each cell; you can see existing support code for that in the template. However, for now, we&#8217;ll just have the cell deselect itself after the selection is made. </p>
<p><pre class="brush: objc;">
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
</pre></p>
<p>Nothing to it here—once the cell is selected, this delegate method is called. We just deselect the same cell. </p>
<h1>Navigation Controllers</h1>
<p>Navigation controllers are often used in conjunction with table views to drill down into a hierarchy of information. You can see this in the Settings app on the iPhone (it&#8217;s not quite the same on the iPad). Like tab bar controllers, nav controllers are container controllers, in that the majority of their content comes from another view controller. We&#8217;ll create a nav controller as part of our tab bar and set our table as its root view controller. </p>
<p>Go into AppDelegate.m and import GraphicsTableViewController.h. Before the creation of the tab bar controller, add the following code:</p>
<p><pre class="brush: objc;">
	GraphicsTableViewController *graphicsTableViewController = [[GraphicsTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
	UINavigationController *graphicsNavController = [[UINavigationController alloc] initWithRootViewController:graphicsTableViewController];
	navController.title = @&quot;Graphics Demo&quot;;
</pre></p>
<p>Add the nav controller to the tab bar&#8217;s array. Now build and run the app, and you&#8217;ll see a third tab in the tab bar. Select it, and you&#8217;ll see a table view with all the data we&#8217;ve configured. Click on a cell to select it; it&#8217;ll briefly glow blue before fading again. </p>
<p>In this post we&#8217;ve covered the basics of populating table views and nav controllers, two fundamental tenets of the iOS SDK. Download the project <a href="http://dl.dropbox.com/u/7828009/Cups%20of%20Cocoa/SDK%20Demo%20v5.zip">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/511/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=511&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2011/12/17/the-jungle-part-5-table-views-and-nav-controllers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/12/screen-shot-2011-12-17-at-6-44-05-pm.png" medium="image">
			<media:title type="html">Group Table View Appearance</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/12/screen-shot-2011-12-17-at-7-33-49-pm.png" medium="image">
			<media:title type="html">Xcode Jump Lists</media:title>
		</media:content>
	</item>
		<item>
		<title>The Jungle, Part 4: Automatic Reference Counting</title>
		<link>http://cupsofcocoa.com/2011/11/27/the-jungle-part-4-automatic-reference-counting/</link>
		<comments>http://cupsofcocoa.com/2011/11/27/the-jungle-part-4-automatic-reference-counting/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 01:17:33 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Series]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=499</guid>
		<description><![CDATA[ARC is a new technology introduced at WWDC 2011 that greatly simplifies memory management tasks.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=499&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So far, we have been manually doing our memory management according to the <a href="http://cupsofcocoa.com/2011/04/11/objective-c-lesson-10-memory-management/">basic rules</a> established a long time ago. This method is still fine and is still the standard way to do it, but at WWDC 2011 Apple unveiled the revolutionary ARC technology. ARC stands for <strong>Automatic Reference Counting</strong> which does exactly what it sounds like—it automates the reference counting steps for you. It follows the exact same rules as the old memory management implementations, just automated for you. Rather than doing a runtime cleanup, as <a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)">garbage collection</a> does (a process which slows the running of your program at random intervals), the compiler looks at your code and automatically inserts retain, release, and autorelease calls as necessary. In this way, the performance of your application isn&#8217;t impacted in the least but it could save you a lot of work—after all, computers were designed to do menial labor like that. </p>
<p>In this post we&#8217;ll convert our existing project to ARC. Once we&#8217;re there, little work remains in memory management. Basically, ARC frees us from thinking about memory management at all, so upon finishing the conversion process we won&#8217;t be dealing with memory management anymore. Let&#8217;s get started. </p>
<h1>Converting to ARC</h1>
<p>Open our project and go to Edit &gt; Refactor &gt; Convert to Objective-C ARC…. You&#8217;ll get a sheet that says &#8220;Select Targets to Convert&#8221;; select the only option the list which should be called &#8220;SDK Demo.app (SDK Demo)&#8221;. Then click Precheck. Xcode will build your project then present a new sheet with an introduction. </p>
<div id="attachment_503" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-5-47-44-pm1.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-5-47-44-pm1.png?w=600" alt="ARC Conversion Intro Screen" title="ARC Conversion Intro Screen"   class="size-full wp-image-503" /></a><p class="wp-caption-text">ARC Conversion Intro Screen</p></div>
<p>Click Next and it&#8217;ll say &#8220;Generating Preview&#8221; for a few moments. The sheet will then expand, providing you with a two column view of your code. </p>
<div id="attachment_506" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-5-52-50-pm2.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-5-52-50-pm2.png?w=600" alt="Revisions Editor" title="Revisions Editor"   class="size-full wp-image-506" /></a><p class="wp-caption-text">Revisions Editor</p></div>
<p>To the very left you&#8217;ll see a list of files. In the main content, the left pane is the new code; the right pane is what you currently have. Changed lines are shaded in blue with a darker blue outline; changed code is highlighted in a salmon-esque color (by default). You can go through the list of files on the left (there should be five) and see the changes that ARC will do for you. You&#8217;ll notice that in the properties, retain is replaced by the new keyword strong; in the implementation files dealloc methods are stripped away, as are retain, release, and autorelease calls. The latter methods are now obsolete and you can&#8217;t actually call them anymore. Dealloc is not subject to the same treatment, but unless you&#8217;re doing some custom cleanup that goes beyond freeing memory, you shouldn&#8217;t have your own dealloc. Review the changes, and click Save in the lower-right. </p>
<p>Now Build &amp; Run the app and when it comes in the Simulator you&#8217;ll notice that everything works just as before. …And, that&#8217;s it! Converting an app to ARC is just that easy. Note though, that in some cases the compiler may encounter cases where it can&#8217;t directly convert your code, in which case it&#8217;ll issue an error which you will have to address before you can run your app. This is often the case with files you might receive as part of someone else&#8217;s code library. In those cases, it is usually best to allow the original developer to support ARC or not as necessary. For the time being though, you can turn off ARC on a per-file basis to suppress those errors and run the code with the existing memory management code. </p>
<h1>Selectively Turning Off ARC</h1>
<p>To do so, select the Top Level project in the File Navigator, and select the name of your Target in the pane immediately to the right. Then in the main content pane, select Build Phases from the top, and expand the disclosure triangle next to &#8220;Compile Sources&#8221;. </p>
<div id="attachment_507" class="wp-caption aligncenter" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-6-23-37-pm2.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-6-23-37-pm2.png?w=600" alt="Disable ARC per file by going to Build Phases &gt; Compile Sources" title="Build Phases &gt; Compile Sources"   class="size-full wp-image-507" /></a><p class="wp-caption-text">Disable ARC per-file here</p></div>
<p>Select one or more files that you wish to exclude from ARC, and then hit Return on the keyboard. A little text field will appear. Inside that field, type</p>
<p><pre class="brush: objc;">-fno-objc-arc</pre></p>
<p>Which is a <em>compiler flag</em> to turn off ARC for those files. Hit Done and you&#8217;ll see the flag appear next to the files you&#8217;ve selected. </p>
<h1>Compatibility</h1>
<p>ARC code is fully supported in iOS 5, as well as OS X 10.7 Lion. In addition, most of ARC (exceptions detailed below) is supported in iOS 4 and OS X 10.6 Snow Leopard. </p>
<h1>Language Changes</h1>
<p>Converting a simple app like ours to ARC is not difficult. But ARC adds and modifies more of the Objective-C language, and these changes are worth talking about.</p>
<h2>Autorelease Pools</h2>
<p>Before ARC, you created autorelease pools like any other object and drained them when you&#8217;re done. However, because <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">autorelease</span> is no longer supported by the language, the old method wouldn&#8217;t work very well. So a new method had to be devised. Take a look at main.m, in the Supporting Files group. You&#8217;ll see code like this:</p>
<p><pre class="brush: objc;">@autoreleasepool {
	    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
	}</pre></p>
<p>There now exists a brace-delineated block for autorelease pools. All objects created within the block are autoreleased; the exact moment of autorelease is still determined by the ARC system. Therefore, in cases when you need to create an autorelease pool and release it independently from the main one (perhaps in a tight loop where you&#8217;re creating many autoreleased objects), just enclose the entire loop in the new block. </p>
<h2>New Keywords</h2>
<p>In our conversion process, <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">retain</span> was replaced by <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">strong</span>. This makes sense, as <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">retain</span> is no longer available. <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">strong</span> means the same thing—it states it is a strong relationship, that the class owns (and should &#8220;retain&#8221;) the property. Its counterpart is <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">weak</span>, which means that it is a weak reference. This is especially important when you have a loop reference—for example, if you have a chess game, then you might have a <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">Grid</span> class which keeps track of many <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">Piece</span>s , but at the same time each <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">Piece</span> has a reference back to its owning <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">Grid</span>. In such a case, if the references in both directions were strong, then neither object could be released because they&#8217;d both have a +1 retain count to each other, and you&#8217;ll leak the memory. A weak reference prevents this issue because it does not actually increment the retain count. </p>
<p>Note though that weak references are only supported on iOS 5 and OS X Lion. In previous versions, you&#8217;ll have to use <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">unsafe_unretained</span>, which is a more general keyword that offers you less &#8220;protection&#8221; by the compiler. It also maintains a weak reference, but it doesn&#8217;t guarantee anything else; therefore, you have to make sure that the value is valid when you access it to prevent bad access errors. </p>
<p>If you want to declare ivars with the same characteristics (and you should, just to be clear and to help the compiler out), prefix the keywords with two underscores:</p>
<p><pre class="brush: objc;">__strong, __weak, __unsafe_unretained</pre></p>
<h2>Minor Issues</h2>
<p>In my experiences I&#8217;ve come across two anomalies when using ARC:</p>
<ul>
<li>If you are using a switch statement and you are declaring a new local variable as the first line of each case, you&#8217;ll have to surround each case with curly braces immediately after the colon and after the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">break;</span> or you&#8217;ll get a warning about the variable being out of scope.</li>
<li>There may be presentation issues with UIPopoverController on the iPad, where the application may crash with the error that the popover had been released before the popover had been dismissed. I will continue to investigate this issue and file a bug report with Apple if necessary. For the moment, a solution seems to be to create a strong property for it to always keep a reference to it.</li>
</ul>
<p>ARC greatly simplifies app development on Apple platforms and allows it to catch up to other languages with garbage collection, without the overhead imparted by garbage collection (which is in fact significant on a mobile device like the iPhone; even desktop OS X apps rarely use GC). There are more obscure aspects of ARC than I&#8217;ve covered here, including bridged casting which you might see if you start working with C code or some lower-level Foundation and Core Foundation classes. I&#8217;ll talk about them as we come to them. If you&#8217;re curious, feel free to check out the <a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html">official ARC documentation</a>.</p>
<p>And as usual, download the newest version of the project <a href="http://dl.dropbox.com/u/7828009/Cups%20of%20Cocoa/SDK%20Demo%20v4.zip">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/499/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=499&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2011/11/27/the-jungle-part-4-automatic-reference-counting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-5-47-44-pm1.png" medium="image">
			<media:title type="html">ARC Conversion Intro Screen</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-5-52-50-pm2.png" medium="image">
			<media:title type="html">Revisions Editor</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/11/screen-shot-2011-11-27-at-6-23-37-pm2.png" medium="image">
			<media:title type="html">Build Phases &#62; Compile Sources</media:title>
		</media:content>
	</item>
		<item>
		<title>The Jungle, Part 3: Flipping and Tab Bars</title>
		<link>http://cupsofcocoa.com/2011/11/03/the-jungle-part-3-flipping-and-tab-bars/</link>
		<comments>http://cupsofcocoa.com/2011/11/03/the-jungle-part-3-flipping-and-tab-bars/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 01:35:35 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Series]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[UITabBarController]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=489</guid>
		<description><![CDATA[Tab bar controllers allow you to switch between different "modes" of an app.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=489&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In previous tutorials we&#8217;ve been using some basic UIKit elements on standard views. Today, we&#8217;re going to add a tab bar to our application and wire it up; it&#8217;ll pave the way for some more compelling future expansions. Tab bars are more involved than the regular views we&#8217;ve been using; in additional to simply setting and accessing properties, we also have to contend with a specific controller and design pattern, as well as delegates. Let&#8217;s get started. </p>
<h1>Tab Bar Controllers</h1>
<p>In most cases, tab bars are used with UITabBarController. You may use an independent tab bar if you&#8217;re using it to display the same information in the same view, just sorted differently, for example. However, if you plan on swapping views around, you should use the controller because it manages the swapping mechanism and paradigms for you.</p>
<p>According to Apple&#8217;s documentation, &#8220;The UITabBarController class implements a specialized view controller that manages a radio-style selection interface.…[Y]ou use instances of it as-is to present an interface that allows the user to choose between different modes of operation. This tab bar interface displays tabs at the bottom of the window for selecting between the different modes and for displaying the views for that mode.&#8221; Tab bars are prevalent in many of the standard iOS apps, including Clock and Music. </p>
<p>Rather than accessing the tab bar itself (Apple claims that &#8220;You should never access the tab bar view of a tab bar controller directly&#8221;), you should pass the tab bar controller an array of UIViewControllers (or subclasses of it) to a property called <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">viewControllers</span>. The ordering in the array determines the order of the tabs. Alternatively, you can configure the tabs&#8217; order, title and icon in Interface Builder. When a tab is selected, the controller will load the root view controller for the corresponding tab in the main content view. This means that if you&#8217;ve drilled into a navigation stack (which we will be covering in a future post), you will be returned back to the top of the stack, even if you tap the tab you&#8217;re currently on. By default the state of the view is not saved; however, you can do initial configuration in your own controllers to do so. Any class can become the <a href="http://cupsofcocoa.com/2011/04/04/objective-c-lesson-9-protocols/">delegate</a> of the tab bar and receive notifications about changes. As per the nature of delegation, this is completely optional; proper configuration in Interface Builder means that the view swapping will work fine without having to create a delegate.</p>
<h1>Getting Started</h1>
<p>Today we&#8217;ll be creating a second view controller to have something to switch to, and then we&#8217;ll create a tab bar controller and implement the switching. The process is really intuitive once you know where to begin—so let&#8217;s begin!</p>
<p>Begin by creating a New File in Xcode. Make sure UIViewController subclass is selected in the Template pane and click Next. <div id="attachment_490" class="wp-caption alignright" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2011/11/1.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/11/1.png?w=600" alt="" title="New UIViewController Subclass"   class="size-full wp-image-490" /></a><p class="wp-caption-text">New UIViewController Subclass File</p></div>The Class name should be FlipViewController. It should be a Subclass of UIViewController, not be targeted for iPad, and have a XIB for the user interface. Click Next, and then Create (unless you want to change the file save location or the group the new files get placed under—go ahead). You&#8217;ll get three new files—FlipViewController.h, FlipViewController.m, and FlipViewController.xib. Here, we&#8217;ll create a very simple view that implements a flip-over view like you might see in the Weather or Stocks app. </p>
<p>Start by creating two UIViews in the header, making sure to declare them as IBOutlets and calling them frontView and backView. In the XIB, drag out two UIViews from the Library. Connect the views—Control drag from the File&#8217;s Owner (the first icon on the strip to the left) down to the views and make the connections as you&#8217;re used to. In the view you&#8217;ve designated to be the front, choose a dark color for the Background and then drag out a UIButton. In the Attributes Inspector, next to Type, select Info Light to get you the little &#8220;<em>i</em>&#8221; button that you&#8217;ve seen around iOS. Align that with the bottom right corner of the view. Also in each view, add a label  with &#8220;Front view&#8221; and &#8220;Back view&#8221;, just for reference. In your back view, add a regular UIButton in the upper left corner with the text &#8220;Done&#8221;. This follows the standard UI design pattern—if you&#8217;re using an info button to go to another view, the info button should be in the lower-right corner; a Done button to return sometimes may be in a nav bar (which we&#8217;ll cover in a later post), but is usually in the upper-left corner.</p>
<p>Now connect the actions. The method to go <em>to</em> the back view should be called <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">flipToBack:</span> and take a sender. The method to go back should be called <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">flipToFront:</span> and also take a sender. Of course, make sure the methods are defined in the header, save both the header and the XIB, and go to the .m file. Synthesize the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">frontView</span> and <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">backView</span>. Add the following line to <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">viewDidLoad</span> after the existing code:</p>
<p><pre class="brush: objc;">[self.view addSubview:self.frontView];</pre></p>
<p>This will make the <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">frontView</span> visible. Next we&#8217;ll implement the flipping methods:</p>
<p><pre class="brush: objc;">- (IBAction)flipToBack:(id)sender {
	[UIView transitionFromView:self.frontView toView:self.backView
			  duration:1.0 
			   options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionFlipFromRight)
		        completion:NULL];
}

- (IBAction)flipToFront:(id)sender {
	[UIView transitionFromView:self.backView toView:self.frontView
			  duration:1.0 
			   options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionFlipFromLeft)
			completion:NULL];
}</pre></p>
<p>These methods are rather similar. We&#8217;re calling new UIView animation methods introduced with iOS 4 that replaced a more verbose and complicated system from before; these methods also take advantage of <em>blocks</em> which were also new with iOS 4 and, again, will be covered in the future. Here, we&#8217;re asking it to transition from one view to another. It&#8217;ll draw one view, and then animate in the other based on the options you pass in. The duration is the length of the time you want the animation to take. The options are a <a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html#jumpTo_87">list of options</a> (at the end of the page) you can pass in; you can combine them any way you want (barring conflicting options) using the bitwise OR operator ( <span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">|</span> ) and enclosing the group in parentheses. Here, we&#8217;re telling the animation to use a smooth, natural ease-in and then ease-out at the end. Other options include a linear path, or just ease-in or just ease-out. Finally, you can pass a block in when the animation completes; we&#8217;re not going to do anything here for the moment. Our view controller is done—so let&#8217;s build our tab bar controller.</p>
<h1>Creating the Tab Bar Controller</h1>
<p>Open AppDelegate.h and add a tab bar controller property:</p>
<p><pre class="brush: objc;">@property (nonatomic, retain) UITabBarController *tabBarController;</pre></p>
<p>Synthesize the property. In the implementation, import FlipViewController.h and then release tabBarController in the dealloc method. Then create the tab bar controller:</p>
<p><pre class="brush: objc;">RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@&quot;RootViewController&quot; bundle:nil];
rootViewController.title = @&quot;Root View Controller&quot;;
FlipViewController *flipViewController = [[FlipViewController alloc] initWithNibName:@&quot;FlipViewController&quot; bundle:nil];
flipViewController.title = @&quot;Flip View Controller&quot;;
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:rootViewController, flipViewController, nil];
self.window.rootViewController = self.tabBarController;</pre></p>
<p>First we create the view controllers and set their title. The title of the view controllers is the title that the tab bar displays. We then create a tab bar controller and set the view controllers as an array. You then set the root view controller as before.</p>
<p>If you run the program now, you&#8217;ll get a working app with a tab bar at the bottom. Switch between the tabs and go to the Flip View Controller—and you&#8217;ll realize the issue we have. The tab bar is in fact obscuring the flip button. The solution is rather simple—go to FlipViewController.xib. <div id="attachment_491" class="wp-caption alignleft" style="width: 603px"><a href="http://cupsofcocoa.files.wordpress.com/2011/11/2.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/11/2.png?w=600" alt="" title="Simulated Tab Bar &amp; Moved Button"   class="size-full wp-image-491" /></a><p class="wp-caption-text">Simulated Tab Bar &amp; Moved Button</p></div>Select the front view and move up the Info button. Select the front view itself and go to the Attributes Inspector. Under Simulated Metrics, select Tab Bar from the list next to Bottom Bar. Using that as a guide, position the info button. Build and run again. The flip view will work as you&#8217;ve seen in other Apple apps. </p>
<h1>Apple&#8217;s Progression</h1>
<p>In iOS 5, Apple&#8217;s recommended way to create controllers is through code in the App Delegate. In previous versions you&#8217;d have started with a MainWindow.xib which you can configure in Interface Builder. I feel that because from now on all project templates will feature this new code, it is important to get to know it. </p>
<p>You can download the current iteration of the file <a href="http://dl.dropbox.com/u/7828009/Cups%20of%20Cocoa/SDK%20Demo%20v3.zip">here</a>. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/489/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/489/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/489/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/489/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/489/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/489/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/489/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/489/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=489&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2011/11/03/the-jungle-part-3-flipping-and-tab-bars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/11/1.png" medium="image">
			<media:title type="html">New UIViewController Subclass</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/11/2.png" medium="image">
			<media:title type="html">Simulated Tab Bar &#38; Moved Button</media:title>
		</media:content>
	</item>
		<item>
		<title>The Jungle, Part 2: More UI Elements</title>
		<link>http://cupsofcocoa.com/2011/10/20/the-jungle-part-2-2/</link>
		<comments>http://cupsofcocoa.com/2011/10/20/the-jungle-part-2-2/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 02:00:54 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Series]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Project]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.com/?p=470</guid>
		<description><![CDATA[This week we&#8217;re going to continue from Part 1 and explore additional UI elements. Before we begin though, a bit of (old) news—iOS 5.0 was released on Wednesday, and with it Xcode 4.2. As such, from now on I will be working with Xcode 4.2 and the 5.0 SDK. Once we get the basics down [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=470&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This week we&#8217;re going to continue from <a href="http://cupsofcocoa.com/2011/09/24/the-jungle-part-1/">Part 1</a> and explore additional UI elements. Before we begin though, a bit of (old) news—iOS 5.0 was released on Wednesday, and with it Xcode 4.2. As such, from now on I will be working with Xcode 4.2 and the 5.0 SDK. Once we get the basics down we can discuss compatibility with older versions and how to check the system version, but we&#8217;ll use the newest and greatest for now. </p>
<p>As usual, Xcode 4.2 is <a href="http://itunes.apple.com/us/app/xcode/id448457090?mt=12">available on the App Store</a>. The Xcode 4.2 build is 4D199 (you&#8217;d be surprised how difficult it was to find that anywhere else—important if you&#8217;re upgrading from a Developer Preview), which you can get either from the Welcome screen or by going to Xcode &gt; About Xcode. There is an installation issue floating around in which you may be constantly installing 4.1. In that case, I&#8217;d recommend <a href="http://macdevelopertips.com/xcode/how-to-uninstall-xcode.html">uninstalling Xcode</a> first, and then running the &#8220;Install Xcode.app&#8221; that the App Store downloads. That fixed the problem for me. </p>
<p>Once Xcode is installed, open up the project from last time, and dive into RootViewController.xib.</p>
<h1>Interface First</h1>
<p>With Xcode 4&#8242;s integration of Interface Builder and the code, it breaks down the boundaries of code versus interface and allows you to easily jump back and forth as ideas come into your head. This time, we&#8217;ll put together the interface first and then hook it up to code—even to code that doesn&#8217;t exist yet. </p>
<p>First, start by moving the text field up a bit so we have some more vertical room below. Drag it up, following the blue guidelines, until it snaps into place a bit below the button. </p>
<p><div id="attachment_474" class="wp-caption aligncenter" style="width: 270px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-1.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-1.png?w=600" alt="Segmented Control Settings" title="Segmented Control Settings"   class="size-full wp-image-474" /></a><p class="wp-caption-text">Segmented Control Properties</p></div><br />
Drag out a Segmented Control and place it near the middle of the screen. Extend the width until you get to the blue guidelines at the left and right of the screen. Go to the Attributes Inspector, and use the Segment pop-up menu to select &#8220;Segment 0 &#8211; First&#8221;. Underneath, change the Title to &#8220;Colors&#8221; and watch the change propagate to the UI as well. Change the title of the second segment to &#8220;Progress&#8221; using the pop-up to change the segment. </p>
<p>The segmented control works similar to the tabs you see across OS X, especially in System Preferences—users expect them to &#8220;swap&#8221; view content to something else, and they are usually placed <em>above</em> the content that you expect to swap. For simpler views it may be easy enough to place views overlapping each other and hide or show them as necessary (UIView has a hidden property that can be set to YES or NO). However, this is quite cumbersome and doesn&#8217;t scale very well. A better alternative is to create a plain UIView and set that to individual views as necessary. Therefore, drag out a basic UIView, align it underneath the segmented control, make it as wide, and drag it down until the blue guidelines appear at the bottom. It should look like this:</p>
<div id="attachment_475" class="wp-caption aligncenter" style="width: 370px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-2.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-2.png?w=600" alt="Main View" title="Main View"   class="size-full wp-image-475" /></a><p class="wp-caption-text">New Main View</p></div>
<p>Now select the view, and copy (Command-C) it. Click outside of the main view (on the main canvas area) and paste (Command-V). You should get a blank view the size of the original, floating around on the canvas. Click on the canvas again, and paste another view. They will be the views you&#8217;ll swap in with the segmented control. </p>
<p>Set the background of both views to Group Table View Background Color. It may be easier to set their color to transparent, but this has a major impact on drawing performance—it is much faster to set a specific opaque color. </p>
<p>Drag out UI elements from the Library to build two views like you see here. The exact positioning doesn&#8217;t matter, but make sure to get the correct elements. The first view contains a standard UIView at the top with the Background color set to 50% gray (click on the left part of the Background control in the inspector to get the standard OS X color picker). Underneath are four labels, right-aligned with a standard shadow (most UI text in iOS is drawn with a shadow) and four sliders next to the labels. Here, don&#8217;t worry about the edge guidelines—go right up to the edge of the view. You&#8217;ve already accounted for the edge guides in the main view.</p>
<div id="attachment_476" class="wp-caption aligncenter" style="width: 333px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-3.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-3.png?w=600" alt="Sliders View" title="Sliders View"   class="size-full wp-image-476" /></a><p class="wp-caption-text">Sliders View</p></div>
<p>The second view contains a few more elements—a bold-font label, a regular-font label, a stepper control (new in iOS 5), another bold-font label, a switch, a progress view, and a button. None of the views except the labels have been customized away from their default appearance. The regular label should have its text set to 0%, rather than the standard &#8220;Label&#8221;.</p>
<div id="attachment_477" class="wp-caption aligncenter" style="width: 330px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-4.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-4.png?w=600" alt="Progress View" title="Progress View"   class="size-full wp-image-477" /></a><p class="wp-caption-text">Progress View</p></div>
<p>We have to set some properties on the stepper for it to work with us. Select it then open the Utilities Inspector. The Minimum value should stay at 0 but the Maximum should go up to 100. Increase the Step to 10 to have it change by 10, from 0 to to 100. Also, select the progress view and set the Progress to 0.</p>
<h1>Making Connections</h1>
<p>Our interface design is now done, so let&#8217;s make the connections. Open the Assistant editor (The second button in the &#8220;Editor&#8221; group in the toolbar). Make sure the file in the right pane is RootViewController.h (you can use the jump bar). Control-drag from the blank view in the main view to a blank line in your header. You&#8217;ll get a gray rectangle that says &#8220;Insert Outlet or Outlet Collection&#8221;. <div id="attachment_478" class="wp-caption aligncenter" style="width: 520px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-5.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-5.png?w=600" alt="New Connection" title="New Connection"   class="size-full wp-image-478" /></a><p class="wp-caption-text">New Connection</p></div> Let go, and you get a little popup that lets you configure the outlet name and type. Call the outlet sectionView. Click Connect, and a new property will appear with a blue flash. To connect the other smaller views, you&#8217;ll have to Control-drag from the icons on the left edge of the IB view to the code. See screenshot below:</p>
<div id="attachment_479" class="wp-caption aligncenter" style="width: 520px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-6.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-6.png?w=600" alt="Connection from Sidebar" title="Connection from Sidebar"   class="size-full wp-image-479" /></a><p class="wp-caption-text">Connection from Sidebar</p></div>
<p>The view with the sliders should be called colorsView; the other should be called progressView. </p>
<div id="attachment_480" class="wp-caption alignright" style="width: 379px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-6b.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-6b.png?w=600" alt="New Outlet Popup" title="New Outlet Popup"   class="size-full wp-image-480" /></a><p class="wp-caption-text">New Outlet Popup</p></div>
<p>Then, connect all five elements in the colorsView to the header as well—displayColor, redSlider, greenSlider, blueSlider, and alphaSlider. The progressView isn&#8217;t quite as straight-forward, but it&#8217;s not difficult. Connect the label next to &#8220;Fill:&#8221; as amountLabel, the stepper as amountStepper, the switch as animatedSwitch, and the progress view as progressIndicator. </p>
<p>Now we&#8217;ll connect the actions. Start off with one of the sliders—right click on one of them, and scroll down until you find the Value Changed Event. <div id="attachment_481" class="wp-caption alignleft" style="width: 338px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-7.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-7.png?w=600" alt="Control Events" title="Control Events"   class="size-full wp-image-481" /></a><p class="wp-caption-text">Control Events</p></div> Click and drag from the circle to the right until you come to a new line underneath the actions—you&#8217;ll get a blue line you&#8217;ll be familiar with now. You&#8217;ll get the gray rectangle that says &#8220;Insert Action&#8221; this time. In the pop-up, call the method colorSliderChanged. Next to Arguments, select &#8220;None&#8221; from the menu. Click Connect. Now do the same with the other sliders, but rather than dragging to a new line, drag until the colorSliderChanged method becomes highlighted. You&#8217;ll connect to that method, rather than creating a new one. </p>
<p>We&#8217;ll use a slightly different way to connect the button&#8217;s action. Control-drag from the &#8220;Reset&#8221; button to a new line underneath the actions. The default option will connect an outlet, but we want an action. From the Connections popup menu, choose Action instead. Change the name to resetContent. <div id="attachment_482" class="wp-caption aligncenter" style="width: 327px"><a href="http://cupsofcocoa.files.wordpress.com/2011/10/pic-8.png"><img src="http://cupsofcocoa.files.wordpress.com/2011/10/pic-8.png?w=600" alt="New Action Popup" title="New Action Popup"   class="size-full wp-image-482" /></a><p class="wp-caption-text">New Action Popup</p></div> Note that the event is &#8220;Touch Up Inside&#8221;, the default for buttons. Arguments should again be None.</p>
<p>Connect the stepper control in the same way. Name should be fillAmountChanged; Arguments should be None. Note the default event, &#8220;Value Changed&#8221; for the segmented control. Arguments should be None.</p>
<p>Finally, we&#8217;ll have to connect the segmented control as well. Follow the same process as before. The name should be sectionChanged. Arguments should be Sender. </p>
<h1>Writing the Code</h1>
<p>Open RootViewController.m and scroll through the file. You&#8217;ll note a bunch of synthesized properties, ivars added to the dealloc method, and blank methods for all the actions you just connected. This saves us a lot of boilerplate code and lets us get right down to work. Put in a blank line in the colorSliderChanged method after the opening brace. This method will change the fill color of that gray rectangle based on the slider values, converting to an RGB-A color.  Note though that this isn&#8217;t necessarily a recommended way to do it—it can be slow on older devices. </p>
<p>We&#8217;ll create four float variables to hold the values of the sliders, then create a UIColor instance based off the floats. Then we assign that as the background color of the blank view. The code for the method:</p>
<pre><span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">- (IBAction)colorSliderChanged {
	float redColor = self.redSlider.value;
	float greenColor = self.greenSlider.value;
	float blueColor = self.blueSlider.value;
	float alphaValue = self.alphaSlider.value;
	UIColor *newBackground = [UIColor colorWithRed:redColor green:greenColor blue:blueColor alpha:alphaValue];
	self.displayColor.backgroundColor = newBackground;
}</span></pre>
<p>Next, let&#8217;s handle the case where the stepper&#8217;s value is changed. First we need to update the label, which we&#8217;ve already connected. We grab the stepper&#8217;s value, and create a string out of that. Then we assign the string to the label&#8217;s text property. Next, we&#8217;ll update the progress bar. We use the switch&#8217;s on property to determine if we should animate, and use the stepper&#8217;s value to determine where to fill to. </p>
<pre><span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">- (IBAction)fillAmountChanged {
	NSInteger amount = (NSInteger)self.amountStepper.value;
	// You need two percents to "escape" it and actually display a percent sign
	NSString *amountString = [NSString stringWithFormat:@"%d%%", amount];
	self.amountLabel.text = amountString;
	[self.progressIndicator setProgress:((float)amount / 100.0) animated:self.animatedSwitch.on];
}</span></pre>
<p>The reset method is easy. We&#8217;re just assigning some properties.</p>
<pre><span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">- (IBAction)resetContent:(id)sender {
	self.amountStepper.value = 0.0;
	self.amountLabel.text = @"0%";
	[self.animatedSwitch setOn:YES animated:YES];
	[self.progressIndicator setProgress:0.0 animated:YES];
}</span></pre>
<p>There&#8217;s one last bit that we have to handle—view swapping. Right now if you run the project you&#8217;ll just get a white rectangle on screen and you&#8217;ll not get any of our new code. A simple method like this will fix the issue:</p>
<pre><span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">- (IBAction)sectionChanged:(id)sender {
	UISegmentedControl *sectionControl = (UISegmentedControl *)sender;
	if (sectionControl.selectedSegmentIndex == 0)		// Colors section
		[self.sectionView addSubview:self.colorsView];
	else if (sectionControl.selectedSegmentIndex == 1)	// Progress section
		[self.sectionView addSubview:self.progressView];
}</span></pre>
<p>In this method, we&#8217;re simply adding the correct view to our main placeholder view as necessary. </p>
<p>Now the code is complete. But if you run it, you&#8217;ll see an obvious problem—the first time you run, you&#8217;ll get a blank white rectangle. It&#8217;s only when you select a segment in the segmented control that you get a view. Let&#8217;s fix that by adding this one line to viewDidLoad:</p>
<pre><span style="font-family:'Panic Sans', 'DejaVu Sans Mono', 'Bitstream Vera', Consolas, Inconsolata, Monaco, Menlo, Courier;">[self.sectionView addSubview:self.colorsView];</span></pre>
<p>We know that the first view to load will be the colors view, so automatically we&#8217;ll add that view. If you build and run now, you&#8217;ll get the fully working app.</p>
<h1>UIKit From Here</h1>
<p>As you&#8217;ve seen, using UIKit controls is rarely very difficult or involved. 85% of the time you&#8217;re just setting and getting properties on the controls. Some of them have a custom setter that allows you to animate the change. There are some other controls that we haven&#8217;t really covered, but they&#8217;re not difficult. We&#8217;ll get into putting a tab bar into our application (and its corresponding controller) next time. For now though, if you would like to experiment around, feel free. Also check out <a href="http://developer.apple.com/devcenter/ios/index.action">Apple&#8217;s documentation</a>. You can download this version of the sample project <a href="http://dl.dropbox.com/u/7828009/Cups%20of%20Cocoa/SDK%20Demo%20v2.zip">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/470/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=470&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2011/10/20/the-jungle-part-2-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-1.png" medium="image">
			<media:title type="html">Segmented Control Settings</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-2.png" medium="image">
			<media:title type="html">Main View</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-3.png" medium="image">
			<media:title type="html">Sliders View</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-4.png" medium="image">
			<media:title type="html">Progress View</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-5.png" medium="image">
			<media:title type="html">New Connection</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-6.png" medium="image">
			<media:title type="html">Connection from Sidebar</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-6b.png" medium="image">
			<media:title type="html">New Outlet Popup</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-7.png" medium="image">
			<media:title type="html">Control Events</media:title>
		</media:content>

		<media:content url="http://cupsofcocoa.files.wordpress.com/2011/10/pic-8.png" medium="image">
			<media:title type="html">New Action Popup</media:title>
		</media:content>
	</item>
		<item>
		<title>RIP Steve Jobs.</title>
		<link>http://cupsofcocoa.com/2011/10/05/rip-steve-jobs/</link>
		<comments>http://cupsofcocoa.com/2011/10/05/rip-steve-jobs/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 00:16:55 +0000</pubDate>
		<dc:creator>inspire48</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Steve Jobs]]></category>

		<guid isPermaLink="false">http://cupsofcocoa.wordpress.com/?p=466</guid>
		<description><![CDATA[R.I.P Steve Jobs<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=466&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>He truly was a great man. Namaste.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cupsofcocoa.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cupsofcocoa.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cupsofcocoa.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cupsofcocoa.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cupsofcocoa.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cupsofcocoa.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cupsofcocoa.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cupsofcocoa.wordpress.com/466/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cupsofcocoa.com&#038;blog=15412068&#038;post=466&#038;subd=cupsofcocoa&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cupsofcocoa.com/2011/10/05/rip-steve-jobs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/212c6d7a99d93b7a5b929c9421164a59?s=96&#38;d=identicon&#38;r=X" medium="image">
			<media:title type="html">inspire48</media:title>
		</media:content>
	</item>
	</channel>
</rss>
