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

<channel>
	<title>Bob McCune &#187; iOS</title>
	<atom:link href="http://www.bobmccune.com/category/ios/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bobmccune.com</link>
	<description>iOS and Java Design, Development, Training, and Mentoring</description>
	<lastBuildDate>Thu, 15 Sep 2011 06:55:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Screen Capture in iOS Apps</title>
		<link>http://www.bobmccune.com/2011/09/08/screen-capture-in-ios-apps/</link>
		<comments>http://www.bobmccune.com/2011/09/08/screen-capture-in-ios-apps/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 01:44:03 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=423</guid>
		<description><![CDATA[I occasionally come across the need to grab the contents of a view as an image. This is often the result of needing to perform some non-stock, animated transition between views, but there are a variety of reasons why this might be useful. Thanks to the Core Animation framework&#8217;s CALayer class, this is easy to [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I occasionally come across the need to grab the contents of a view as an image. This is often the result of needing to perform some non-stock, animated transition between views, but there are a variety of reasons why this might be useful. Thanks to the Core Animation framework&#8217;s <code>CALayer</code> class, this is easy to do.</p>
<p>All <code>UIView</code> instances have an underlying instance of a <code>CALayer</code>. The layer is responsible for rendering the view&#8217;s contents and performing any view-related animations. CALayer defines a method called <code>renderInContext:</code> which allows you to render the layer, and its sublayers, into a given graphics context:</p>
<pre>
UIGraphicsContext context = // some graphics context
[viewToCapture.layer renderInContext:context];
</pre>
<p>Before you can access any layer-specific APIs, you&#8217;ll need to make sure you&#8217;re linking against the QuartzCore framework. Xcode&#8217;s default templates don&#8217;t link against this framework so you&#8217;ll need to select <em>Target Name</em> &gt; Build Phases &gt; Link Binary With Libraries and select <code>QuartzCore.framework</code>.</p>
<p><img src="http://www.bobmccune.com/wp-content/uploads/2011/09/xcode_linking.png" alt="" title="xcode_linking" width="597" height="278" class="alignnone size-full wp-image-435" /></p>
<p>Additionally, you&#8217;ll need to add the following import to your code wherever you are calling the layer&#8217;s properties or methods:</p>
<pre>#import &lt;QuartzCore/QuartzCore.h&gt;</pre>
<p>With the necessary project configuration out of the way, the next question is where do we get a graphics context into which we can render the view&#8217;s content? This can be created using UIKit&#8217;s <code>UIGraphicsBeginImageContextWithOptions</code> function which will create a new bitmap-based graphics context for us.</p>
<pre>UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);</pre>
<p>This function takes a <code>CGSize</code> (you view&#8217;s size), a <code>BOOL</code> indicating if your view is opaque, and a <code>CGFloat</code> specifying the scaling factor. If you&#8217;re rendering a fully opaque, rectangular view you can pass YES for the <code>opaque</code> argument so the alpha channel can be discarded from the context.</p>
<p>Now that we&#8217;ve created a graphics context we can use the <code>UIGraphicsGetCurrentContext()</code> and <code>UIGraphicsGetImageFromCurrentImageContext()</code> functions to get reference to this new context and retrieve the rendered image data from it. Finally, we&#8217;ll want to call the <code>UIGraphicsEndImageContext()</code> function to clean up this context and remove it from the stack. Putting all this together we end up with the following:</p>
<pre>// Render the views layer contents into the current Graphics context
CGSize viewSize = viewToCapture.bounds.size;
UIGraphicsBeginImageContextWithOptions(viewSize, NO, 1.0);
[viewToCapture.layer renderInContext:UIGraphicsGetCurrentContext()];
// Read the UIImage object
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
</pre>
<p>To see this code in action I&#8217;ve put together a simple demo app. You can tap on Archer, Lana, or the background to capture the contents of the view and write the image to your Photo Library.</p>
<p><img src="http://www.bobmccune.com/wp-content/uploads/2011/09/archerlana.png" alt="" title="archerlana" width="500" height="350" class="alignnone size-full wp-image-438" /></p>
<p><strong>Note:</strong> Before running the demo be sure to open the &#8220;Photos&#8221; app on the Simulator so it can initialize its database or the images won&#8217;t be written. Enjoy!</p>
<p><a href='http://www.bobmccune.com/wp-content/uploads/2011/09/SnapMe.zip'>Download Demo</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/09/08/screen-capture-in-ios-apps/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Quick Github PSA</title>
		<link>http://www.bobmccune.com/2011/09/06/quick-github-psa/</link>
		<comments>http://www.bobmccune.com/2011/09/06/quick-github-psa/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 06:38:09 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=416</guid>
		<description><![CDATA[My Core Animation Demos projects was previously available on Github under my personal account, but I have since moved it to my business account. The new location of of the CA demos is: https://github.com/tapharmonic/Core-Animation-Demos I haven&#8217;t made any major changes to code at this point, however, I did start an ARC branch to house my [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>My Core Animation Demos projects was previously available on Github under my personal account, but I have since moved it to my business account.  The new location of of the CA demos is:</p>
<p><a href="https://github.com/tapharmonic/Core-Animation-Demos">https://github.com/tapharmonic/Core-Animation-Demos</a></p>
<p>I haven&#8217;t made any major changes to code at this point, however, I did start an ARC branch to house my ongoing ARC changes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/09/06/quick-github-psa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automagic Factories in Objective-C</title>
		<link>http://www.bobmccune.com/2011/04/08/automagic-factories-in-objective-c/</link>
		<comments>http://www.bobmccune.com/2011/04/08/automagic-factories-in-objective-c/#comments</comments>
		<pubDate>Fri, 08 Apr 2011 14:00:39 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=374</guid>
		<description><![CDATA[The Factory pattern is a frequently used creational pattern to help abstract the creation of an object from its clients. Although there are a few specializations of this pattern I&#8217;ll focus on the most commonly used approach and then look at how we can leverage the Objective-C Runtime to make this solution more robust. Let&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><img src="http://www.bobmccune.com/wp-content/uploads/2011/04/magic_hat.png" alt="" title="magic_hat" width="150" height="150" class="alignright size-full wp-image-377" />The <a href="http://www.oodesign.com/factory-pattern.html">Factory</a> pattern is a frequently used <a href="http://www.oodesign.com/creational-patterns/">creational pattern</a> to help abstract the creation of an object from its clients.  Although there are a few specializations of this pattern I&#8217;ll focus on the most commonly used approach and then look at how we can leverage the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html">Objective-C Runtime</a> to make this solution more robust.</p>
<p>Let&#8217;s begin by creating a simple command-line app that creates <code>Animal</code> objects and gets them to speak on command.  The various animal objects will all inherit from the <em>abstract</em> <code>Animal</code> class.<br />
<span id="more-374"></span></p>
<pre>
@interface Animal : NSObject {
}

- (void)speak;
- (NSString *)key;

@end
</pre>
<pre>
@implementation Animal

- (void)speak {
    NSAssert(NO, @"The 'speak' method must be implemented by subclass.");
}

- (NSString *)key {
    // Animal instances will be 'keyed' by their lower case class name
    // Overly simplistic, but will suffice for now
    return [NSStringFromClass([self class]) lowercaseString];
}

@end
</pre>
<p>With the abstract base class complete let&#8217;s create a couple concrete <code>Animal</code> implementations:</p>
<pre>
@implementation Cat
- (void)speak {
    NSLog(@"Meow, Meow...");
}
@end
</pre>
<pre>
@implementation Dog
- (void)speak {
    NSLog(@"Bark, Bark...");
}
@end
</pre>
<p>Our <code>Cat</code> &amp; <code>Dog</code> objects are ready to go so let&#8217;s integrate them into our app and get them to speak.</p>
<pre>
int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Animal *cat = [[Cat alloc] init];
    [cat speak];
    [cat release];

    Animal *dog = [[Dog alloc] init];
    [dog speak];
    [dog release];

    [pool drain];
    return 0;
}
</pre>
<p>Running this app will produce the following console output:</p>
<pre>
Meow, Meow...
Bark, Bark...
</pre>
<p>This works as we&#8217;d expect, but the main problem with using the <code>Cat</code> and <code>Dog</code> classes this way is <em>coupling</em>.  Even though we&#8217;ve defined our variables as abstract <code>Animal</code> types we&#8217;re still coupled to the specific subtypes.  This means we can&#8217;t modify our <code>Animal</code> types or evolve their creation without impacting our client code.  This may seem like a trivial matter in this example, but these design decisions can have major impacts on real-world applications.  Let&#8217;s avoid some of the potential ripple effects by introducing a <em>factory</em>.</p>
<h2>Creating Animals</h2>
<p>We&#8217;ll begin by moving the object creation responsibilities from our client to a new object called <code>AnimalFactory</code>.  This factory, as you may have guessed, will be responsible for creating and vending instances of <code>Animal</code>.  A simple, but common implementation of this could be defined as follows:</p>
<pre>
@implementation AnimalFactory

+ (AnimalFactory *)factory {
    return [[[[self class] alloc] init] autorelease];
}

- (Animal *)animalForKey:(NSString *)animalKey {
    Animal *animal = nil;
    if ([animalKey isEqualToString:@"dog"]) {
        animal = [[Dog alloc] init];
    } else if ([animalKey isEqualToString:@"cat"]) {
        animal = [[Cat alloc] init];
    } else {
        NSAssert(NO, @"No Animal found for key:'%@'", animalKey);
    }
    return [animal autorelease];
}

@end
</pre>
<p>The <code>AnimalFactory</code> will determine which instance to create based on the argument passed to the <code>animalForKey:</code> method.  It creates the appropriate instance and returns an <em>autoreleased</em> version of it to the client.  To use this new factory in our client we can make the following changes:</p>
<pre>
AnimalFactory *factory = [AnimalFactory factory];

[[factory animalForKey:@"cat"] speak];
[[factory animalForKey:@"dog"] speak];
</pre>
<p>If you were to run this example again you would see the same output as before, but the introduction of this factory has helped us resolve two specific limitations in our previous implementation:</p>
<ol>
<li>The client is no longer coupled to a particular instance of <code>Animal</code>.  As our requirements change the factory can return alternate instances (<code>FatCat</code>, <code>HotDog</code>, etc.) without impacting our client code.</li>
<li>The client is no longer in the business of object creation which means <em>how</em> an animal is instantiated is no longer its concern.  Additionally, by returning an autoreleased instance we don&#8217;t unnecessarily force memory management responsibilities onto the client.</li>
</ol>
<p>One outstanding problem we have is with the factory itself.  Although the client is better decoupled from the specific types and their creation, the factory itself is not.  Every time we add a new animal to the app we additionally have to make modifications to the factory.  </p>
<blockquote><p>
    <span style="foreground-color: darkGray"><em>[Informercial Guy Voice]</em></span>&nbsp;&nbsp;<strong>There&#8217;s got to be a better way!</strong>
</p></blockquote>
<h2>Enter the Objective-C Runtime</h2>
<p>
Objective-C is a dynamic language where many decisions are deferred until runtime.  This deferment allows for some of the more interesting capabilities of the language and is made possible through the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html">Objective-C Runtime</a>.  Although you can successfully use Objective-C without having much awareness of the runtime, understanding how to interact with it can open up some interesting new possibilities.  </p>
<p>
It would be nice if our <code>AnimalFactory</code> could automatically find and dispense all instances of <code>Animal</code> without us having to continuously modify the factory.  Thanks to the runtime, it can.</p>
<h2>Automagic Factories</h2>
<p>Let&#8217;s begin by creating a utility class called <code>RuntimeUtils</code> containing a method to allow us to dynamically find all instances of a particular type.  This method will be implemented as follows:</p>
<pre>
+ (NSArray *)classStringsForClassesOfType:(Class)filterType {

    int numClasses = 0, newNumClasses = objc_getClassList(NULL, 0);
    Class *classList = NULL;

    while (numClasses < newNumClasses) {
        numClasses = newNumClasses;
        classList = realloc(classList, sizeof(Class) * numClasses);
        newNumClasses = objc_getClassList(classList, numClasses);
    }

    NSMutableArray *classesArray = [NSMutableArray array];

    for (int i = 0; i < numClasses; i++) {
        Class superClass = classList[i];
        do {
            // recursively walk the inheritance hierarchy
            superClass = class_getSuperclass(superClass);
            if (superClass == filterType) {
                [classesArray addObject:NSStringFromClass(classList[i])];
                break;
            }
        } while (superClass);
    }

    free(classList);

    return classesArray;
}
</pre>
<p>This method makes use of two functions defined in <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html"><code>&lt;objc/runtime.h&gt;</code></a>:</p>
<ol>
<li><code>objc_getClassList</code> - This function returns a list of all classes registered with the app.  We'll loop through this list and then filter its results.</li>
<li><code>class_getSuperclass</code> - Returns the superclass of a class.  We recursively walk the inheritance hierarchy of each class to determine if it's a descendant of <code>Animal</code>.  If so, we add its class string to our array.
</ol>
<p>With our <code>RuntimeUtils</code> class now ready, let's go back and revisit the implementation of our factory object.</p>
<h2>Implementing the Magic</h2>
<p>We'll change the implementation of our factory class to leverage this new <code>RuntimeUtils</code> class.  We'll start by implementing the <code>init</code> method.</p>
<pre>
- (id)init {
  if ((self = [super init])) {
    NSArray *animalClassStrings = [RuntimeUtils classStringsForClassesOfType:[Animal class]];
    animals = [[NSMutableDictionary alloc] initWithCapacity:[animalClassStrings count]];
      for (id classString in animalClassStrings) {
        Class animClass = NSClassFromString(classString);
        Animal *animal = [[animClass alloc] init];
        [animals setObject:animal forKey:[animal key]];
        [animal release];
      }
    }
  return self;
}
</pre>
<p>Our <code>init</code> implementation starts by finding all the class strings for the classes extending <code>Animal</code>.  We iterate through the results creating an instance of each class and storing its pointer in the <code>animals</code> dictionary.  With the <code>init</code> method complete let's modify the <code>animalForKey:</code> method.</p>
<pre>
- (Animal *)animalForKey:(NSString *)animalKey {
    Animal *animal = [animals objectForKey:animalKey];
    NSAssert(animal, @"No animal found.  Invalid 'animalType' specified?");
    return animal;
}
</pre>
<p>We now have a greatly simplified <code>animalForKey:</code> method.  Gone are the <code>if/else</code> or <code>switch</code> statements you'd typically see in a factory method.  Instead, we have a simple, generic execution path regardless of the number of animals we add to the application.</p>
<p>To see the benefits of our revamped <code>AnimalFactory</code>, let's make a couple additions to our animal kingdom.</p>
<pre>
@implementation Monkey
- (void)speak {
    NSLog(@"Ooo, Ooo, Eee, Eee");
}
@end
</pre>
<pre>
@implementation Bird
- (void)speak {
    NSLog(@"Tweet, tweet");
}
@end
</pre>
<p>We can go back to our client code and make the following changes:</p>
<pre>
[[factory animalForKey:@"dog"] speak];
[[factory animalForKey:@"cat"] speak];
<strong>[[factory animalForKey:@"monkey"] speak];</strong>
<strong>[[factory animalForKey:@"bird"] speak];</strong>
</pre>
<p>If you run the application again you'll see the new <code>Monkey</code> and <code>Bird</code> instances were automatically registered with the factory without any additional changes!  Winning!</p>
<h2>Conclusion</h2>
<p>Although this was clearly a contrived example, it hopefully illustrates how leveraging the Objective-C Runtime can result in significantly more flexible factory objects.  Some simple modifications could be made to this approach to provide for lazy instantiation or handle more complex object creation.  In a future post I'll provide a more concrete example of how this strategy can be put to good use in a real-world application.</p>
<h2>Resources</h2>
<p><a href="http://www.bobmccune.com/wp-content/uploads/2011/04/AutomagicFactories.zip">Sample Code</a></br><br />
<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html">Objective-C Runtime Reference</a></br><br />
<a href="http://cocoasamurai.blogspot.com/2010/01/understanding-objective-c-runtime.html">Understanding the Objective-C Runtime</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/04/08/automagic-factories-in-objective-c/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Core Animation Presentation</title>
		<link>http://www.bobmccune.com/2011/03/13/core-animation-presentation/</link>
		<comments>http://www.bobmccune.com/2011/03/13/core-animation-presentation/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 00:22:48 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=320</guid>
		<description><![CDATA[This past week I gave a presentation on Core Animation to the Minnesota CocoaHeads user group. Core Animation is a truly amazing framework and is really the magic ingredient in the iOS user experience. Understanding how to effectively use it can allow you to add new levels of realism and interactivity to your apps. As [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>This past week I gave a presentation on <a href="http://developer.apple.com/technologies/ios/graphics-and-animation.html">Core Animation</a> to the <a href="http://www.cocoaheadsmn.org/">Minnesota CocoaHeads</a> user group.  Core Animation is a truly amazing framework and is really the magic ingredient in the iOS user experience.  Understanding how to effectively use it can allow you to add new levels of realism and interactivity to your apps.</p>
<p>As part of the presentation I prepared a number of examples ranging from image effects to 3D animations (OK, 2 1/2 D animations).  If you&#8217;re interested in taking a look you can find the demo on <a href="https://github.com/bobmccune/Core-Animation-Demos">github</a> and the slides are available <a href="http://www.bobmccune.com/works/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/03/13/core-animation-presentation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>iOS 101: Pattern Images</title>
		<link>http://www.bobmccune.com/2011/03/08/ios-101-pattern-images/</link>
		<comments>http://www.bobmccune.com/2011/03/08/ios-101-pattern-images/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 20:37:02 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=304</guid>
		<description><![CDATA[A common need in an iOS app is to tile a background image on a UIView. It&#8217;s trivial to implement, but not particularly obvious if you&#8217;re new to the platform. The solution is to set the view&#8217;s backgroundColor property to a UIColor instance created from your pattern image. For instance, the following code will create [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>A common need in an iOS app is to tile a background image on a <code>UIView</code>.  It&#8217;s trivial to implement, but not particularly obvious if you&#8217;re new to the platform.  The solution is to set the view&#8217;s <code>backgroundColor</code> property to a <code>UIColor</code> instance created from your pattern image.  For instance, the following code will create a pattern image from <code>pattern.png</code>:</p>
<pre>
- (void)viewDidLoad {
  [super viewDidLoad];
  UIImage *patternImage = [UIImage imageNamed:@"pattern.png"];
  self.view.backgroundColor = [UIColor colorWithPatternImage:patternImage];
}
</pre>
<p>This will produce the following effect:</p>
<p><a href="http://www.bobmccune.com/wp-content/uploads/2011/03/pattern_to_view.png"><img src="http://www.bobmccune.com/wp-content/uploads/2011/03/pattern_to_view.png" alt="" title="Pattern to View" width="505" height="493" class="alignnone size-full wp-image-310" /></a></p>
<p>Like most things in Cocoa there is usually an easy solution to the problem you&#8217;re trying to solve, but what it is may not be immediately apparent if you&#8217;re just starting out.  Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/03/08/ios-101-pattern-images/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using iOS 4&#8242;s IBOutletCollection</title>
		<link>http://www.bobmccune.com/2011/01/31/using-ios-4s-iboutletcollection/</link>
		<comments>http://www.bobmccune.com/2011/01/31/using-ios-4s-iboutletcollection/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 23:17:32 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=220</guid>
		<description><![CDATA[Cocoa has long defined the IBAction and IBOutlet keywords. These keywords provide metadata hints to Interface Builder providing it some understanding of your underlying code so you can graphically wire instance variables and properties and set target-action behaviors. For instance, whenever you need a pointer to NIB-defined object you would create a property defined as: [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Cocoa has long defined the IBAction and IBOutlet keywords.  These keywords provide metadata hints to Interface Builder providing it some understanding of your underlying code so you can graphically wire instance variables and properties and set target-action behaviors.  For instance, whenever you need a pointer to NIB-defined object you would create a property defined as:</p>
<pre>
@interface MainViewController : UIViewController {
    UIButton *saveButton;
}
@property (nonatomic, retain) <strong>IBOutlet</strong> UIButton *saveButton;
@end
</pre>
<p>The inclusion of the <code>IBOutlet</code> keyword in the saveButton&#8217;s property definition makes it visible to Interface Builder allowing this connection to be wired graphically as show below:</p>
<p><img src="http://www.bobmccune.com/wp-content/uploads/2011/01/save.png" alt="Interface Builder" title="save" width="346" height="269" class="alignnone size-full wp-image-239" /></p>
<p>Using IBOutlet makes it very easy to define your UI in Interface Builder and simply &#8220;wire&#8221; the object references to your code.  However, it does come with one major drawback in that the relationship from a NIB-defined object to property/ivar is always 1-to-1; there was no way to define a collection of components as a single property in your code.  Thankfully, Apple quietly introduced a new keyword in iOS4+ called IBOutletCollection allowing you to do just this.  Let&#8217;s take a closer look at an example where this can be useful.</p>
<h2>IBOutletCollection</h2>
<p>Like the other keywords previously mentioned, you&#8217;ll find the IBOutletCollection keyword in UINibDeclarations.h, which is part of the UIKit framework.  The new keyword is defined as follows:</p>
<pre>
#ifndef IBOutletCollection
#define IBOutletCollection(ClassName)
#endif
</pre>
<p>You&#8217;ll notice that <code>IBOutletCollection</code> takes a class name parameter.  This allows you specify what are considered valid values for the collection such as <code>UIView</code> or <code>UIButton</code>.  If you&#8217;d prefer you can change the &#8220;type&#8221; argument to <code>id</code> to allow for a heterogeneous collection.  So how could this be useful?</p>
<h2>Putting IBOutletCollection To Work</h2>
<p>I&#8217;ve often found times where I needed references to certain components, but really only in an aggregate way so I could change state on them as a group.  To do this I&#8217;d first need to define separate ivar/property combinations for each component, wire them up in Interface Builder, and then manually collect each pointer into an NSArray and store the collection for later use.  Although this works, it is rather tedious and does add unnecessary bloat to your code.  A better way to handle this type of scenario is to make use of the IBOutletCollection keyword and wire up this relationship in IB.  </p>
<p>In the example below I&#8217;ve defined two unique ivars/properties to hold references to my on &#038; off buttons and then an NSArray to hold a collection of other buttons.  The on/off buttons are used to change the <code>enabled</code> state of the group of &#8220;otherButtons&#8221;.</p>
<pre>
@interface MainViewController : UIViewController {
    UIButton *onButton;
    UIButton *offButton;
    NSArray  *otherButtons;
}

@property (nonatomic, retain) IBOutlet UIButton *onButton;
@property (nonatomic, retain) IBOutlet UIButton *offButton;
@property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *otherButtons;

- (IBAction)toggleButtons:(id)sender;

@end
</pre>
<pre>
@implementation MainViewController

- (void)setButtonsState:(BOOL)state {
   for (id button in self.otherButtons) {
      [button setEnabled:state];
   }
   self.onButton.enabled = !state;
   self.offButton.enabled = state;
}

- (void)viewDidLoad {
   [super viewDidLoad];
   [self setButtonsState:YES];
}

- (IBAction)toggleButtons:(id)sender {
   [self setButtonsState:sender == onButton];
}

- (void)dealloc {
   self.onButton = nil;
   self.offButton = nil;
   self.otherButtons = nil;
   [super dealloc];
}

@synthesize onButton, offButton, otherButtons;

@end
</pre>
<p>I can now easily wire this together in Interface Builder without the need to write any code to collect and store the references to my group of buttons.  This is clearly a contrived example, but I hope you can see the benefit of this small addition to iOS 4.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/01/31/using-ios-4s-iboutletcollection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iPhone Jam Session</title>
		<link>http://www.bobmccune.com/2010/04/08/iphone-jam-session/</link>
		<comments>http://www.bobmccune.com/2010/04/08/iphone-jam-session/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 00:17:14 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Presentation]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=151</guid>
		<description><![CDATA[Thanks to everyone who turned out for the iPhone presentation Chris Bartling and I gave at last night&#8217;s Jam Session! We had a great time talking about a fun topic. I hope you enjoyed it. There were some questions about Apple&#8217;s approval process. I mentioned that I just submitted an app this past Saturday and [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Thanks to everyone who turned out for the iPhone presentation <a href="http://bartling.blogspot.com/">Chris Bartling</a> and I gave at last night&#8217;s Jam Session!  We had a great time talking about a fun topic.  I hope you enjoyed it.</p>
<p>There were some questions about Apple&#8217;s approval process.  I mentioned that I just submitted an app this past Saturday and said I didn&#8217;t know how soon it would be before it was given the thumbs up.  I wish I had checked my email during the break as it was approved last night.  That&#8217;s not too bad a turnaround time.  Thanks Apple!</p>
<p>Thanks again and I hope I&#8217;ll see some of you at next month&#8217;s CocoaHeads.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2010/04/08/iphone-jam-session/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

