<?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>fill the void</title>
	<atom:link href="http://www.bdunagan.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bdunagan.com</link>
	<description></description>
	<lastBuildDate>Tue, 02 Mar 2010 05:04:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>iPhone Tip: Larger Hit Area for UIButton</title>
		<link>http://www.bdunagan.com/2010/03/01/iphone-tip-larger-hit-area-for-uibutton/</link>
		<comments>http://www.bdunagan.com/2010/03/01/iphone-tip-larger-hit-area-for-uibutton/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 05:04:04 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=672</guid>
		<description><![CDATA[Apple&#8217;s iPhone HIG estimates 44&#215;44 pixels is a good hit area for a UI element. If the button isn&#8217;t that big, don&#8217;t let the user realize that: make the hit area larger than the button.
The UINavigationItem button is an excellent example of this larger hit area. Try touching near (but not on) the standard &#8220;Back&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/DesigningNativeApp/DesigningNativeApp.html#//apple_ref/doc/uid/TP40006556-CH4-SW16">Apple&#8217;s iPhone HIG</a> estimates 44&#215;44 pixels is a good hit area for a UI element. If the button isn&#8217;t that big, don&#8217;t let the user realize that: make the hit area larger than the button.</p>
<p>The <tt>UINavigationItem</tt> button is an excellent example of this larger hit area. Try touching near (but not on) the standard &#8220;Back&#8221; button in any navigation-based iPhone app. It responds. I never even noticed this interaction until I started this post, and that&#8217;s precisely the goal.</p>
<p>But when Apple doesn&#8217;t auto-extend the hit area, the developer should. There are two approaches:</p>
<ul>
<li>programmatically grow button&#8217;s hit area via <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/hitTest:withEvent:"><tt>UIView::hitTest</tt></a>
<li>hooking up a larger invisible button to the visible one.
</ul>
<p>For the invisible button, use Interface Builder to create a large <tt>UIButtonTypeCustom</tt> <tt>UIButton</tt>, hook up its <tt>touchDown</tt>, <tt>touchUpInside</tt>, <tt>touchUpOutside</tt> events to custom selectors in the controller, and use <tt>UIButton::setHighlighted</tt> on the original button to mimic a real tap, as described in this spot-on <a href="http://stackoverflow.com/questions/808503/uibutton-making-the-hit-area-larger-than-the-default-hit-area/818774#818774">StackOverflow comment</a>. (And don&#8217;t try setting the button&#8217;s alpha to zero; the button will no longer respond to touch events.)</p>
<p>Either way, an oversized hit area is especially necessary for smaller buttons, like the 29&#215;31 &#8220;Detail Disclosure&#8221; button (<tt>UIButtonTypeDetailDisclosure</tt>) or the 18&#215;19 &#8220;Info Light&#8221; button (<tt>UIButtonTypeInfoLight</tt>). Try simply adding the &#8220;Info Light&#8221; <i>i</i> button to a blank screen, running it on a device, and tapping it; it&#8217;s frustratingly small. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/03/01/iphone-tip-larger-hit-area-for-uibutton/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Codesigning on Different OS Versions</title>
		<link>http://www.bdunagan.com/2010/02/27/codesigning-on-different-os-versions/</link>
		<comments>http://www.bdunagan.com/2010/02/27/codesigning-on-different-os-versions/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 21:49:15 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=627</guid>
		<description><![CDATA[A couple days ago, I was trying to codesign the latest application bundle when I got a very strange error message:


bdunagan$ codesign -f -s 'EMC Corporation' 'Retrospect.app'
codesign_allocate: for architecture i386 object:
/Retrospect.app/Contents/MacOS/Retrospect malformed object (unknown load command 5)
Retrospect.app: object file format invalid or unsuitable


Googling for those exact phrases lead nowhere. Eventually, I came across an excellent [...]]]></description>
			<content:encoded><![CDATA[<p>A couple days ago, I was trying to codesign the latest application bundle when I got a very strange error message:<br />
<br/></p>
<pre>
bdunagan$ codesign -f -s 'EMC Corporation' 'Retrospect.app'
codesign_allocate: for architecture i386 object:
/Retrospect.app/Contents/MacOS/Retrospect malformed object (unknown load command 5)
Retrospect.app: object file format invalid or unsuitable
</pre>
<p><br/><br />
Googling for those exact phrases lead nowhere. Eventually, I came across an excellent <a href="http://stackoverflow.com/questions/2022888/cant-add-growl-framework-to-release-version-of-my-app/2024843#2024843">StackOverflow comment</a> from Apple employee Chris Espinosa: different OSes. In fact, that was the problem. The application bundle was built on 10.6 and I was trying to use <tt>codesign</tt> on 10.5. Doesn&#8217;t work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/27/codesigning-on-different-os-versions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create iTunes Link Arrows</title>
		<link>http://www.bdunagan.com/2010/02/25/create-itunes-link-arrows/</link>
		<comments>http://www.bdunagan.com/2010/02/25/create-itunes-link-arrows/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 03:04:50 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=645</guid>
		<description><![CDATA[iTunes has a great user interface affordance for adding actions to text: clickable arrows embedded right next to the text. (Perhaps Apple wanted to avoid an interface filled with blue, underlined text.) I haven&#8217;t found any formal name for them in Apple&#8217;s HIG, so I call them link arrows (or jump arrows). Sadly, this is [...]]]></description>
			<content:encoded><![CDATA[<p>iTunes has a great user interface affordance for adding actions to text: clickable arrows embedded right next to the text. (Perhaps Apple wanted to avoid an interface filled with blue, underlined text.) I haven&#8217;t found any formal name for them in <a href="http://developer.apple.com/Mac/library/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html">Apple&#8217;s HIG</a>, so I call them link arrows (or jump arrows). Sadly, this is my <i>third</i> post on recreating link arrows. My <a href="http://www.bdunagan.com/2008/09/05/cocoa-tutorial-itunes-link-arrows/">first post</a> was a first pass at the problem, whereas my <a href="http://www.bdunagan.com/2008/11/10/cocoa-tutorial-link-arrows-part-2/">second post</a> looked a bit better but not great.</p>
<p>This time, the UI looks right, and clicking works as expected. I wrote up a small sample app to demo the link arrows; see <a href="http://code.google.com/p/bdunagan/source/browse/#svn/trunk/LinkArrows">Google Code</a>.</p>
<p><img src="/files/LinkArrows_highlighted.png"/><br />
<br/><br />
<img src="/files/LinkArrows_clicked.png"/><br />
<br/><br />
<img src="/files/LinkArrows_highlighted_not_key.png"/></p>
<p>The key is tracking. In the previous post, I used <tt>NSCell::hitTestForEvent</tt> to detect whether a click &#8220;hit&#8221; the link arrow image on a mouse down event, but then I immediately acted on it, without waiting for a mouse up event. Jarring and wrong.</p>
<p>I need to track what happens after that initial <tt>NSLeftMouseDown</tt> event. For this, I use <tt>NSCell::trackMouse</tt> to track all relevant mouse events until the next <tt>NSLeftMouseUp</tt> event. Thanks to <a href="http://developer.apple.com/mac/library/samplecode/PhotoSearch/listing9.html">Apple&#8217;s PhotoSearch sample app</a> and <a href="http://code.google.com/p/sequel-pro/source/browse/trunk/Source/SPTextAndLinkCell.m">Rowan Beentje&#8217;s Sequel Pro code</a> for this much needed direction.</p>
<p>There are a couple corner cases I handle in <tt>trackMouse</tt>:</p>
<ul>
<li>mouse down outside => mouse up inside (no click)
<li>mouse down inside => mouse up outside (no click)
<li>mouse down inside => mouse drag out => mouse drag in => mouse up inside (click)
</ul>
<p>These mouse event sequences are what people expect from buttons, and I want people to think of the link arrows as buttons, as iTunes treats them.</p>
<p>Below is the main code from <tt>LinkArrowCell.m</tt>. The rest is just scaffolding.</p>
<pre class="brush: objc;">
// snipped from LinkArrows/LinkArrowCell.m (MIT license)

- (void)drawInteriorWithFrame:(NSRect)aRect inView:(NSView *)controlView {
	NSRect textRect = NSMakeRect(aRect.origin.x, aRect.origin.y, aRect.size.width - kLinkArrowWidth - kLinkArrowWidthPadding, aRect.size.height);

	// Draw text.
	[super drawInteriorWithFrame:textRect inView:controlView];

	// Draw link arrow.
	if ([self shouldDisplayLink]) {
		if (![self isHighlighted]) {
			// The cell is not highlighted.
			[linkArrow setImage:[NSImage imageNamed:@&quot;link_arrow&quot;]];
			[linkArrow setAlternateImage:[NSImage imageNamed:@&quot;link_arrow_click&quot;]];
		}
		else if ([[[self controlView] window] isKeyWindow] &amp;&amp; [[[self controlView] window] firstResponder] == [self controlView]) {
			// The cell is highlighted, and the window is key.
			[linkArrow setImage:[NSImage imageNamed:@&quot;link_arrow_highlight&quot;]];
			[linkArrow setAlternateImage:[NSImage imageNamed:@&quot;link_arrow_click_highlight&quot;]];
		}
		else {
			// The cell is highlighted, but the window is not key.
			[linkArrow setImage:[NSImage imageNamed:@&quot;link_arrow_click&quot;]];
			[linkArrow setAlternateImage:[NSImage imageNamed:@&quot;link_arrow&quot;]];
		}

		[linkArrow drawInteriorWithFrame:[LinkArrowCell linkRect:aRect] inView:controlView];
	}
}

- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView {
	// Figure out hit point in view.
	NSRect linkRect = [LinkArrowCell linkRect:cellFrame];
	NSPoint p = [[[NSApp  mainWindow] contentView] convertPoint:[event locationInWindow] toView:controlView];
	if (p.x &gt; linkRect.origin.x &amp;&amp; p.x &lt; (linkRect.origin.x + linkRect.size.width) &amp;&amp;
		p.y &gt; linkRect.origin.y &amp;&amp; p.y &lt; (linkRect.origin.y + linkRect.size.height)) {
		// Point inside link arrow.
		[linkArrow setState:NSOnState];
		return NSCellHitContentArea | NSCellHitTrackableArea;
	}
	else {
		// Point outside link arrow.
		[linkArrow setState:NSOffState];
		return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];
	}
}

- (BOOL)trackMouse:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
	// Check if link arrow was hit.
	int hitType = [self hitTestForEvent:[NSApp currentEvent] inRect:cellFrame ofView:controlView];
	BOOL isButtonClicked = hitType == (NSCellHitContentArea | NSCellHitTrackableArea);
	if (!isButtonClicked) return YES;

	// Ignore events other than mouse down.
	if ([event type] != NSLeftMouseDown) return YES;

	// Grab all events until a mouse up event.
	while ([event type] != NSLeftMouseUp) {
		// Check if link arrow was hit.
		hitType = [self hitTestForEvent:[NSApp currentEvent] inRect:cellFrame ofView:controlView];
		isButtonClicked = hitType == (NSCellHitContentArea | NSCellHitTrackableArea);
		// Update the cell's display.
		[controlView setNeedsDisplayInRect:cellFrame];
		// Pass event if not hit.
		if (!isButtonClicked) {
			[NSApp sendEvent:event];
		}
		// Grab next event.
		event = [[controlView window] nextEventMatchingMask:(NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSMouseEnteredMask | NSMouseExitedMask)];
	}

	// Perform click only if link arrow was hit.
	if (isButtonClicked) {
		[self performClick:nil];
	}

	return YES;
}
</pre>
<p>Before I went with the <tt>trackMouse</tt> approach, I looked at subclassing <tt>NSCell</tt> and overriding <tt>startTrackingAt</tt>, <tt>continueTracking</tt>, <tt>stopTracking</tt>. For some reason, my overridden methods never triggered. Very odd as <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ControlCell/Tasks/SubclassingNSCell.html#//apple_ref/doc/uid/20000728-BCIBFAHH">Apple&#8217;s <tt>NSCell</tt> docs</a> bring up the approach, and many developers refer to it working on various email lists like <a href="http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg44372.html">cocoa-dev</a>. Still not sure why this path didn&#8217;t work, but <tt>trackMouse</tt> certainly does.</p>
<p>Again, a sample project for this code is at <a href="http://code.google.com/p/bdunagan/source/browse/#svn/trunk/LinkArrows">Google Code</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/25/create-itunes-link-arrows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cocoa Tip: NSApp&#8217;s currentEvent</title>
		<link>http://www.bdunagan.com/2010/02/22/cocoa-tip-nsapps-currentevent/</link>
		<comments>http://www.bdunagan.com/2010/02/22/cocoa-tip-nsapps-currentevent/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 04:05:10 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=636</guid>
		<description><![CDATA[Let&#8217;s say I want to detect a modifier key. This information is embedded in every NSEvent object as flags in the modifierFlags attribute. But what if my current method isn&#8217;t passed an event? The answer is not NSApp&#8217;s nextEventMatchingMask. I explored that option for too long before moving on. The answer is NSApp&#8217;s currentEvent. With [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say I want to detect a modifier key. This information is embedded in every <tt>NSEvent</tt> object as flags in the <tt>modifierFlags</tt> attribute. But what if my current method isn&#8217;t passed an event? The answer is <i>not</i> <tt>NSApp</tt>&#8217;s <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/NSApplication/nextEventMatchingMask:untilDate:inMode:dequeue:"><tt>nextEventMatchingMask</tt></a>. I explored that option for too long before moving on. The answer is <tt>NSApp</tt>&#8217;s <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/NSApplication/currentEvent"><tt>currentEvent</tt></a>. With it, I have easy access to the current event that the application is dealing with. To detect the modifier keys, I simply extract the <tt>modifierFlags</tt> attribute and check it for them.</p>
<pre class="brush: objc;">
// Detect the modifier flags (keys) from the current NSEvent.
NSEvent *event = [NSApp currentEvent];
if (event != nil) {
	BOOL isCommandKey = ([event modifierFlags] &amp; NSCommandKeyMask) != 0;
	BOOL isShiftKey = ([event modifierFlags] &amp; NSShiftKeyMask) != 0;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/22/cocoa-tip-nsapps-currentevent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocoa Tip: Continuous Updates and Bindings</title>
		<link>http://www.bdunagan.com/2010/02/19/cocoa-tip-continuous-updates-and-bindings/</link>
		<comments>http://www.bdunagan.com/2010/02/19/cocoa-tip-continuous-updates-and-bindings/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 03:16:17 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=617</guid>
		<description><![CDATA[Today, I was looking at a UI bug where the value of an NSTextField, populated through Cocoa Bindings, wasn&#8217;t getting saved. I tabbed over to the field, changed the value, tabbed over to the blue &#8220;Done&#8221; button and hit Space. Value saved. No bug. So I tried following the steps to reproduce exactly. Click in [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I was looking at a UI bug where the value of an <tt>NSTextField</tt>, populated through Cocoa Bindings, wasn&#8217;t getting saved. I tabbed over to the field, changed the value, tabbed over to the blue &#8220;Done&#8221; button and hit Space. Value saved. No bug. So I tried following the steps to reproduce exactly. Click in the field; change the value; click &#8220;Done&#8221;. Ah, the value didn&#8217;t save. Turns out, bindings don&#8217;t fire by default for an <tt>NSTextField</tt> unless it loses focus. To get the bindings to fire, I had to go into Interface Builder and check <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/CocoaBindingsRef/Concepts/BindingsOptions.html#//apple_ref/doc/uid/20002304-187448">&#8220;Continuously Updates Value&#8221;</a> (see the screenshot). With that checked, the bindings fired for both <tt>NSControlTextDidEndEditingNotification</tt> and <tt>NSControlTextDidChangeNotification</tt> notifications.</p>
<p><img src="/files/IB_Continuously_Updates_Value.png"/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/19/cocoa-tip-continuous-updates-and-bindings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Tip: Rotating UIView</title>
		<link>http://www.bdunagan.com/2010/02/16/iphone-tip-rotating-uiview/</link>
		<comments>http://www.bdunagan.com/2010/02/16/iphone-tip-rotating-uiview/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 05:51:52 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=609</guid>
		<description><![CDATA[The iPhone OS&#8217;s accelerometer tells me the exact x, y, and z orientation of an iPhone or iPod Touch. Which is freakin&#8217; awesome. To demonstrate how easy it is to leverage, I wrote a bit of code to rotate a UILabel in a simple Utility app. The controller sets itself as the delegate for UIAccelerometer [...]]]></description>
			<content:encoded><![CDATA[<p>The iPhone OS&#8217;s accelerometer tells me the exact <tt>x</tt>, <tt>y</tt>, and <tt>z</tt> orientation of an iPhone or iPod Touch. Which is freakin&#8217; awesome. To demonstrate how easy it is to leverage, I wrote a bit of code to rotate a <tt>UILabel</tt> in a simple Utility app. The controller sets itself as the delegate for <tt>UIAccelerometer</tt> and then responds to the selector <tt>accelerometer:didAccelerate:</tt>. I started by simply using the exact rotation, but that resulted in a <i>very</i> wobbly text label; so, I added a bit of rounding and animation to dampen it.</p>
<pre class="brush: objc;">
// add UIAccelerometerDelegate as a delegate to the controller
// add a UILabel to the XIB and hook it up to the controller
// add QuartzCore framework

// MainViewController.h
@interface MainViewController : UIViewController &lt;UIAccelerometerDelegate&gt; {
	IBOutlet UILabel *textLabel;
}
@end

// MainViewController.m
#import &quot;MainViewController.h&quot;
#import &lt;QuartzCore/QuartzCore.h&gt;

@implementation MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
		// Set this controller as the accelerometer's delegate.
		[[UIAccelerometer sharedAccelerometer] setDelegate:self];
    }
    return self;
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
	// Get the rotation in radians.
	CGFloat rotation = (atan2(acceleration.x, acceleration.y) + M_PI);
	// Dampen it a bit.
	float div = 48 / (2 * M_PI);
	rotation = (int)(rotation * div) / div;
	// Animate the movement a bit.
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDuration:.2];
	textLabel.layer.transform = CATransform3DMakeRotation(rotation, 0, 0, 1);
	[UIView commitAnimations];
}

@end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/16/iphone-tip-rotating-uiview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Tip: Capturing a Shake Event</title>
		<link>http://www.bdunagan.com/2010/02/13/iphone-tip-capturing-a-shake-event/</link>
		<comments>http://www.bdunagan.com/2010/02/13/iphone-tip-capturing-a-shake-event/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 19:05:20 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=604</guid>
		<description><![CDATA[It&#8217;s very easy to detect a shake event in an iPhone app. There are many good posts on StackOverflow about it, but I wanted to consolidate the code into the minimal number of lines. The key is the motionEnded:withEvent: delegate and the view becoming the first responder.

-(BOOL)canBecomeFirstResponder {
    return YES;
}

- (void) viewDidAppear:(BOOL)animated [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s very easy to detect a shake event in an iPhone app. There are many good posts on StackOverflow about it, but I wanted to consolidate the code into the minimal number of lines. The key is the <tt>motionEnded:withEvent:</tt> delegate <i>and</i> the view becoming the first responder.</p>
<pre class="brush: objc;">
-(BOOL)canBecomeFirstResponder {
    return YES;
}

- (void) viewDidAppear:(BOOL)animated {
	[self becomeFirstResponder];
    [super viewDidAppear:animated];
}

- (void) viewDidDisappear:(BOOL)animated {
	[self resignFirstResponder];
	[super viewDidDisappear:animated];
}

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
	if (event.subtype == UIEventSubtypeMotionShake) {
		// TODO: insert code here.
	}
	[super motionEnded:motion withEvent:event];
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/13/iphone-tip-capturing-a-shake-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obligatory iPad Post</title>
		<link>http://www.bdunagan.com/2010/02/11/obligatory-ipad-post/</link>
		<comments>http://www.bdunagan.com/2010/02/11/obligatory-ipad-post/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 08:01:43 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[random]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=582</guid>
		<description><![CDATA[&#8220;When the Mac first came out, Newsweek asked me what I [thought] of it. I said: Well, it’s the first personal computer worth criticizing. So at the end of the presentation, Steve came up to me and said: Is the iPhone worth criticizing? And I said: Make the screen five inches by eight inches, and [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;When the Mac first came out, Newsweek asked me what I [thought] of it. I said: Well, it’s the first personal computer worth criticizing. So at the end of the presentation, Steve came up to me and said: Is the iPhone worth criticizing? And I said: Make the screen five inches by eight inches, and you’ll rule the world.”<br />
- <a href="http://gigaom.com/2010/01/26/alan-kay-with-the-tablet-apple-will-rule-the-world/">Alan Kay in 2007</a></p>
<p>&#8220;Nothing about the iPad is obviously revolutionary, but it didn’t need to be: the iPhone OS and iPhone hardware are already revolutionary.</p>
<p>Apple already reinvented John’s mobile computing and my input mechanics and novice usability in 2007 with the iPhone. We’ve had the truly magical and revolutionary product this entire time, but we take it for granted now, and we’ve forgotten how awesome it already is.&#8221;<br />
- <a href="http://www.marco.org/358002061">Marco Arment from Tumblr and Instapaper</a></p>
<p>&#8220;The iPad as a particular device is not necessarily the future of computing. But as an ideology, I think it just might be. In hindsight, I think arguments over &#8216;why would I buy this if I already have a phone and a laptop?&#8217; are going to seem as silly as &#8216;why would I buy an iPod if it has less space than a Nomad?&#8217;&#8221;<br />
- <a href="http://stevenf.tumblr.com/post/359224392/i-need-to-talk-to-you-about-computers-ive-been">Steven Frank from Panic</a></p>
<p>Not exactly filling the void with an iPad post, particularly one that&#8217;s two weeks late to the party and starts with what smarter people have already said. I blame <a href="http://culturedcode.com/things/">Things</a> for not being more insistent.</p>
<p>I agree that Apple&#8217;s iPad is the next step in computing: simplified computing. Yes, it has its shortcomings (inherent to a 1.0 release, which the iPhone had only <a href="http://news.google.com/archivesearch?q=iphone&#038;scoring=a&#038;hl=en&#038;ned=us&#038;um=1&#038;sa=N&#038;sugg=d&#038;as_ldate=2007/01&#038;as_hdate=2007/01&#038;lnav=hist0">three years ago</a>), but it keeps with the design decisions that made the iPhone/iPod Touch ridiculously popular.</p>
<p>To illustrate the need, let me tell you about the &#8220;Check disc&#8221; incident. Over Christmas, my Dad subscribed to the New York Times Crossword Puzzle. The NYT doesn&#8217;t have an online puzzle component, so he had to download Across Lite, a third party Windows app. He called me after using it for a couple days about a &#8220;disc&#8221; issue. Whenever he tried to save the day&#8217;s puzzle, the app displayed, &#8220;Cannot write to file. Check disc.&#8221; It was such a weird error that I wanted to see it for myself. With VMWare Fusion on my Mac, I installed Across Lite and got the same error within a minute. I didn&#8217;t actually figure out what the problem was (read-only directory?); instead, I simply told my Dad how to use the &#8220;Save As&#8230;&#8221; option to save the puzzle to the Desktop. Problem solved. </p>
<p>But the larger problem is not solved. The incident is a perfect example of the abstraction problems that current computing environments have. They want to deal in apps and documents and photos, but they still break these abstractions daily. Windows gives me app shortcuts available from the Start menu, but those are a mediocre hack to abstract away the monstrous Program Files folder. Mac apps are nicely treated as atomic objects (even though they are folders), but people still run them out of read-only DMGs, leading to equally confusing error messages. All these semi-porous abstractions lead to a lot of unnecessary confusion.</p>
<p>The iPhone OS enforces the abstraction to a much better degree, and we&#8217;ve seen the results: over two billion apps downloaded on seventy million devices in eighteen months. All these little apps are islands of data, a per-app version of the Newton&#8217;s <a href="http://en.wikipedia.org/wiki/Newton_%28platform%29">data soup</a> platform. The iPad simply extends this OS to a larger surface.</p>
<p>I want one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/02/11/obligatory-ipad-post/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocoa Tip: NSImage Composites</title>
		<link>http://www.bdunagan.com/2010/01/25/cocoa-tip-nsimage-composites/</link>
		<comments>http://www.bdunagan.com/2010/01/25/cocoa-tip-nsimage-composites/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 05:39:14 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=575</guid>
		<description><![CDATA[Recently, I wanted to composite together two images, much like Tweetie&#8217;s retweet UI for avatars: display the main icon in its original size but overlay a second icon smaller and offset. Turns out to be only a couple lines of code using NSImage:


NSImage *mainIcon = [NSImage imageNamed:@&#34;main_icon&#34;];
NSImage *overlayIcon = [NSImage imageNamed:@&#34;overlay_icon&#34;];
[mainIcon lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[overlayIcon drawInRect:NSMakeRect([mainIcon [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I wanted to composite together two images, much like Tweetie&#8217;s retweet UI for avatars: display the main icon in its original size but overlay a second icon smaller and offset. Turns out to be only a couple lines of code using <tt><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSImage_Class/Reference/Reference.html">NSImage</a></tt>:</p>
<p><img src="/files/nsimage_composite.png"/></p>
<pre class="brush: objc;">
NSImage *mainIcon = [NSImage imageNamed:@&quot;main_icon&quot;];
NSImage *overlayIcon = [NSImage imageNamed:@&quot;overlay_icon&quot;];
[mainIcon lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[overlayIcon drawInRect:NSMakeRect([mainIcon size].width / 2, 0, [mainIcon size].width / 2, [mainIcon size].width / 2) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
[mainIcon unlockFocus];
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2010/01/25/cocoa-tip-nsimage-composites/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a Menu Bar Item</title>
		<link>http://www.bdunagan.com/2009/12/27/creating-a-menu-bar-item/</link>
		<comments>http://www.bdunagan.com/2009/12/27/creating-a-menu-bar-item/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 03:32:51 +0000</pubDate>
		<dc:creator>bdunagan</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.bdunagan.com/?p=548</guid>
		<description><![CDATA[

On my MacBook Pro, I have a lot of items in the menu bar: Tweetie, LittleSnapper, Jing, Evernote, BusySync, MobileMe, along with the standard set. Recently, when I needed to make my own, I started wondering what they are. Actual apps or app components? Activity Monitor confirmed that most are separate applications, although Tweetie&#8217;s is [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/files/menubaritem_mine.png"/></p>
<p>
On my MacBook Pro, I have a lot of items in the menu bar: Tweetie, LittleSnapper, Jing, Evernote, BusySync, MobileMe, along with the standard set. Recently, when I needed to make my own, I started wondering what they are. Actual apps or app components? Activity Monitor confirmed that most are separate applications, although Tweetie&#8217;s is just a component. Good, so how do I make one?
</p>
<p><img src="/files/menubaritem_plist.png"/></p>
<p>
All I had to do is add a single row to <tt>Info.plist</tt>: set <tt><a href="http://developer.apple.com/mac/library/documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCConcepts/LSCConcepts.html#//apple_ref/doc/uid/TP30000999-CH202-SW11">LSUIElement</a></tt> to true. The other code is boilerplate, creating a controller in Xcode and hooking up some outlets in Interface Builder. I created a quick sample project on <a href="http://code.google.com/p/bdunagan/source/browse/#svn/trunk/MenuBarItem">Google Code</a> under MenuBarItem (screenshot below). Thanks again to <a href="http://glyphish.com/">Glyphish</a> for an awesome set of free icons, including the pictured coffee mug.
</p>
<p><img src="/files/menubaritem_app.png"/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdunagan.com/2009/12/27/creating-a-menu-bar-item/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
