<?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>Danilo Campos.blog &#187; UI</title>
	<atom:link href="http://blog.danilocampos.com/category/ui/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.danilocampos.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 17 Aug 2010 04:28:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>iPhone Development: Force UITableView to show only complete cells</title>
		<link>http://blog.danilocampos.com/2009/10/29/iphone-development-force-uitableview-to-show-only-complete-cells/</link>
		<comments>http://blog.danilocampos.com/2009/10/29/iphone-development-force-uitableview-to-show-only-complete-cells/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 00:49:17 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Neurotic]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[cocoa touch]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=341</guid>
		<description><![CDATA[Tallymander uses UITableViewCells not only to display data but also to manipulate it. That means that partially-visible cells &#8212; that is, those that are cut off at the top or bottom of the view &#8212; aren&#8217;t terribly useful. Better, I thought, would be to always ensure that when a partially-visible cell crops up, the UITableViewController [...]]]></description>
			<content:encoded><![CDATA[<p>Tallymander uses UITableViewCells not only to display data but also to manipulate it. That means that partially-visible cells &#8212; that is, those that are cut off at the top or bottom of the view &#8212; aren&#8217;t terribly useful.</p>
<p>Better, I thought, would be to always ensure that when a partially-visible cell crops up, the UITableViewController will quietly nudge things to be completely visible.</p>
<p><a href="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo6.jpg"><img class="alignnone size-medium wp-image-354" title="Partially visible cells" src="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo6-200x300.jpg" alt="Partially visible cells" width="200" height="300" /></a> vs. <a href="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo-2.jpg"><img class="alignnone size-medium wp-image-355" title="Fully Visible Cells" src="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo-2-200x300.jpg" alt="Fully Visible Cells" width="200" height="300" /></a></p>
<p>In the first image, you can see the only part of the top and bottom cell. In the second image, the cells have been nudged so that everything visible is <em>completely</em> visible. This took a little noodling around with math but it wasn&#8217;t hard to do. Put this method into your UITableViewController subclass:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>snapBottomCell
<span style="color: #002200;">&#123;</span>
	NSInteger cellHeight <span style="color: #002200;">=</span> <span style="color: #2400d9;">62</span>; <span style="color: #11740a; font-style: italic;">//Cells for my view are 62px tall. Sub your own height here</span>
&nbsp;
	NSInteger offsetOverage <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span> self.tableView.contentOffset.y <span style="color: #002200;">%</span> cellHeight;
	<span style="color: #11740a; font-style: italic;">//Use the tableview's contentOffset property and the cell height to determine how much is being cut off</span>
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>offsetOverage <span style="color: #002200;">&amp;</span>gt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">//If the overage is more than 0, we should figure out what the new offset needs to be</span>
&nbsp;
		NSInteger newOffset;
&nbsp;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>offsetOverage <span style="color: #002200;">&amp;</span>gt;<span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>cellHeight<span style="color: #002200;">/</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
		<span style="color: #002200;">&#123;</span>
			newOffset <span style="color: #002200;">=</span> self.tableView.contentOffset.y <span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>cellHeight <span style="color: #002200;">-</span> offsetOverage<span style="color: #002200;">&#41;</span>;
			<span style="color: #11740a; font-style: italic;">//If the overage is greater than or equal to half the height of a cell, pull the cell up so it's fully visible</span>
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
			newOffset <span style="color: #002200;">=</span> self.tableView.contentOffset.y <span style="color: #002200;">-</span> offsetOverage;
			<span style="color: #11740a; font-style: italic;">//Else, push the cell out of view</span>
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #11740a; font-style: italic;">//With the new offset determined, animate the movement:</span>
&nbsp;
		<span style="color: #002200;">&#91;</span>UIView beginAnimations<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span> context<span style="color: #002200;">:</span><span style="color: #a61390;">NULL</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>UIView setAnimationDuration<span style="color: #002200;">:</span><span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>UIView setAnimationCurve<span style="color: #002200;">:</span>UIViewAnimationCurveEaseOut<span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>self.tableView setContentOffset<span style="color: #002200;">:</span>CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, newOffset<span style="color: #002200;">&#41;</span> animated<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>UIView commitAnimations<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>You&#8217;ll need to implement these two delegate methods as well:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>scrollViewDidEndDecelerating<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIScrollView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>scrollView
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>self snapBottomCell<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>scrollViewDidEndDragging<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIScrollView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>scrollView willDecelerate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>decelerate
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>decelerate <span style="color: #002200;">==</span> <span style="color: #a61390;">NO</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>self snapBottomCell<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>And that&#8217;s it. If more than half of the bottom cell is visible, the cell gets nudged completely into view. If less than half is visible, it&#8217;s pushed out of view.</p>
<p>You could change snapBottomCell to accept cellHeight as an argument if you need to accommodate cells with variable heights. You might sort out a particular cell&#8217;s height like so:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">	<span style="color: #400080;">NSIndexPath</span> <span style="color: #002200;">*</span>indexPath <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.tableView indexPathForRowAtPoint<span style="color: #002200;">:</span>CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span>self.tableView.frame.size.height <span style="color: #002200;">-</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #11740a; font-style: italic;">//Get the index path of the cell currently visible at the bottom edge of the tableview</span>
&nbsp;
	UITableViewCell <span style="color: #002200;">*</span>cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.tableView cellForRowAtIndexPath<span style="color: #002200;">:</span>indexPath<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>self snapBottomCell<span style="color: #002200;">:</span>cell.frame.size.height<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>There are cases where this isn&#8217;t useful: long lists whose primary function is selecting data for loading in another view, for example. Still, any time you&#8217;re using UITableViewCells to house controls or chunky bits of data, it might be good to ensure that only whole cells are displayed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/10/29/iphone-development-force-uitableview-to-show-only-complete-cells/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tallymander 2.0 Post-Mortem</title>
		<link>http://blog.danilocampos.com/2009/10/20/tallymander-2-0-post-mortem/</link>
		<comments>http://blog.danilocampos.com/2009/10/20/tallymander-2-0-post-mortem/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 21:14:50 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[tallymander]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=332</guid>
		<description><![CDATA[Tallymander 2.0 has been in the App Store for a few weeks. Here&#8217;s the story on my favorite product, so far. Once upon a time&#8230; Tallymander was born because once upon a time, I worked for the man and that meant wearing fancy pants and shirts that buttoned (the better to establish my image as [...]]]></description>
			<content:encoded><![CDATA[<p>Tallymander 2.0 has been in the App Store for a few weeks. Here&#8217;s the story on my favorite product, so far.</p>
<h2 style="font-size: 1.5em;">Once upon a time&#8230;</h2>
<p>Tallymander was born because once upon a time, I worked for the man and that meant wearing fancy pants and shirts that buttoned (the better to establish my image as a professional and advance my career). About once a month I rounded up my finery, counted it, and took it to the dry cleaners.</p>
<p>My mental math abilities could be bested by a fruit fly so I wondered if the App Store had anything to make the counting easier. They did, but it was either crap or too limited for my needs. The idea for Tallymander was born. I wanted to make something simple but useful.</p>
<p>I expected to make about $40 off of it, but I knew I wanted the challenge so I plowed ahead anyway. 1.0 shipped and people liked it. Really liked it! I got a handful of emails with kudos and feature requests. I wanted to get cracking on <a href="http://www.danilocampos.com/apps/globejot/">GlobeJot</a> but decided I would spend a little time adding some customer requests to Tallymander first. A couple more weeks of development and Tallymander 1.1 was submitted. I forgot all about it.</p>
<p>Until one night, around midnight, when I got the &#8220;Ready for Sale&#8221; email that iPhone developers live for. Tallymander 1.1 was live.</p>
<p>And an App Store Staff Favorite. I peed myself a little. There followed a slew of <a href="http://blog.danilocampos.com/2009/03/20/lots-of-tally-counters/">copycat apps</a> following this prominence. So it goes on the App Store.</p>
<h2 style="font-size: 1.5em;">The future</h2>
<p>Tthanks to a handful of enthusiastic users and a little help from Apple, Tallymander managed to make me a tidy bit more money than the $40 I had expected. About $4,000 to date, in fact. Not bad for an app that started as a two week UX trial.</p>
<p><span id="more-332"></span></p>
<p>It wasn&#8217;t enough for me, though. The best thing about Tallymander was getting emails from customers with wildly unexpected and diverse use cases. I haven&#8217;t gotten a single one that&#8217;s like another. The greatest commonality across all the customer emails boiled down to two main themes: better organization and data analysis.</p>
<p>My customers weren&#8217;t the only ones with ideas on how to make Tallymander better. A minor point release with a bug fix was rejected by Apple in April. The reason? The reviewer didn&#8217;t understand how an existing interface element should work and rejected because it didn&#8217;t work according to his expectations.</p>
<p>The rejection was dumb &#8212; the previous major release that had introduced the interface element in question had been approved just fine. But then it dawned on me: the interface sucks.</p>
<h2 style="font-size: 1.5em;">Kill the sacred cows</h2>
<p>Tallymander&#8217;s interface had won many fans, even at Apple, but there was one problem: it was too inflexible. To tally, you tapped anywhere on a tally&#8217;s cell:</p>
<p><a href="http://www.danilocampos.com/wp-content/uploads/2009/10/IMG_0080.jpg"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="IMG_0080" src="http://www.danilocampos.com/wp-content/uploads/2009/10/IMG_0080.jpg" alt="IMG_0080" width="320" height="480" /></a>Each cell had a little indicator that showed what mode it was in: addition or subtraction. You could temporarily change all modes globally with a sort of &#8220;shift key&#8221; in the toolbar. 1.2 introduced a &#8220;caps lock&#8221; style option for this shift mode, which is when the whole UI, for me, went to hell.</p>
<h2 style="font-size: 1.5em;">Mission 1: Fix the interface</h2>
<p>Tallymander&#8217;s interface, where it worked, worked really well. First, you could count an infinite number of things. Since it used UITableView, which can store as many cells as you want, it could scale to many tasks. Whether you&#8217;re counting two things or twenty, Tallymander had you covered. This was an enormous advantage over some of the other early tallying apps.</p>
<p>The other major benefit was ease of interaction. The hit box for the user to interact with any given tally was 320 x 80 pixels. Large targets are easier to hit. Big win, especially if your attention is on something other than your iPhone.</p>
<p>The secret sauce to Tallymander, the reason why people love it, is the one that has evaded almost every other competitor. There&#8217;s a user-definable tally setting that lets you shake the iPhone to increment the count. Tallymander  vibrates when a successful tally is registered this way. The first time someone does this, their eyes light up. Then they do it again. And again. And again. It <em>feels </em>good. So no matter what else, that had to stay.</p>
<p>Aside from these things, it was time to take the rest of the UI out and shoot it. Shift mode? That sucks. Separate modes to reorder and edit? That&#8217;s crap.</p>
<p>Ending shift mode meant add and subtract had to live together, in harmony, at all times where you&#8217;d be tallying. It took many sketches to get something I wanted, but I ended up with this configuration:</p>
<p><a href="http://www.danilocampos.com/wp-content/uploads/2009/10/oldbasecell.png"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="oldbasecell" src="http://www.danilocampos.com/wp-content/uploads/2009/10/oldbasecell.png" alt="oldbasecell" width="320" height="60" /></a>Tap anywhere on the left, you get subtraction. Tap anywhere on the right, you get addition. The hit box is still pretty generous and the tradeoff in the ease of switching between those two tasks &#8212; just move your finger &#8212; made it worth doing. The cell itself is also smaller so that more tallies can appear onscreen at once. The other major change: no more alarm clock style numerals. They had to be pre-rendered as images and while I liked the look, the pre-rendering limited the kinds of data that could be displayed in the counter field. The new counter is stylized in homage to the old, replacing its seven-segment grunge with clean OLED-style pixelation.</p>
<p>The death of shift mode is exaggerated. It&#8217;s still around, but now it makes more sense. It is <em>config</em> mode and it shifts all cells into a very different realm of tasks: resetting counts and changing tally-specific settings.</p>
<p><a href="http://www.danilocampos.com/wp-content/uploads/2009/10/oldconfigmode.png"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="oldconfigmode" src="http://www.danilocampos.com/wp-content/uploads/2009/10/oldconfigmode.png" alt="oldconfigmode" width="320" height="60" /></a>This works very well. You can switch into config mode, make all the changes you like, then get back to your tallying. This is a lot closer to how the user works: adding and subtracting both fit in the same basic mental mode, in the end, and it&#8217;s counterproductive to separate them.</p>
<p>Best of all, deletion and reordering were reunited as one edit mode:</p>
<p><a style="text-decoration: none;" href="http://www.danilocampos.com/wp-content/uploads/2009/10/photo.jpg"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="photo" src="http://www.danilocampos.com/wp-content/uploads/2009/10/photo.jpg" alt="photo" width="320" height="253" /></a></p>
<p>With addition and subtraction living in one spot with no clearly defined button, it was important to give the user some kind of visual feedback. Most buttons on the iPhone darken as the user touches, then register an action when the touch lifts. This was inappropriate for Tallymander &#8212; counting needs instantaneous feedback. Delays lead to confusion. Instead of darkening a region, Tallymander 2.0 glows according to whatever interaction the user has selected:</p>
<p><a href="http://www.danilocampos.com/wp-content/uploads/2009/10/glow.png"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="glow" src="http://www.danilocampos.com/wp-content/uploads/2009/10/glow.png" alt="glow" width="320" height="60" /></a>The glow matches the color of whatever gem corresponds to the action the user selected. Here, the user has tapped the addition side of the cell. There&#8217;s also a satisfying click sound, for users who want it.</p>
<p>Finally, I hated the initial look of the UI and rebuilt it. The shipping app looks like this:</p>
<p style="text-align: center;">
<p style="text-align: center;"><a style="text-decoration: none;" href="http://www.danilocampos.com/wp-content/uploads/2009/10/Basketball.jpg"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="Basketball" src="http://www.danilocampos.com/wp-content/uploads/2009/10/Basketball.jpg" alt="Basketball" width="192" height="288" /></a></p>
<p style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="BasketBallEditing" src="http://www.danilocampos.com/wp-content/uploads/2009/10/BasketBallEditing.jpg" alt="BasketBallEditing" width="192" height="288" /></p>
<p>The last excision of suck was the reset confirmation. Previously, Tallymander popped up an action sheet asking the user to confirm whether or not they wanted to reset a given count. Time consuming. Worse, this option could be switched off on a per-tally basis, leading to inconsistent expectations. In 2.0, tapping a cell&#8217;s orange reset button puts it into a temporary &#8220;are you sure?&#8221; mode, changing its title label with instructions to confirm. If the user taps again, the count resets. If not, after a brief delay, it switches harmlessly back out into its normal mode.</p>
<p style="text-align: center; "><a href="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo-9.jpg"><img class="aligncenter size-full wp-image-333" title="photo-9" src="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo-9.jpg" alt="photo-9" width="320" height="188" /></a></p>
<p>This lets experienced users quickly reset things while preventing accidental data loss. It&#8217;s a small detail but it&#8217;s one of my favorites.</p>
<p>Another small refinement: the table that contains the tallies will never come to a stop with a tally half-on, half-off the screen. The cells are always nudged so that they&#8217;re completely visible.</p>
<h2 style="font-size: 1.5em;">Mission 2: Customer requests</h2>
<p>You&#8217;ve got a lot of data. You&#8217;ve got questions about your data. What do you do?</p>
<p>If you&#8217;re using a spreadsheet, you type up an equation for some quick analysis. I&#8217;m a huge spreadsheet nerd, so I like this freeform approach. Customers wanted percentages of this and that and while I could easily provide a one-size-fits-all, pre-canned percentage tool, that&#8217;s not how I roll.</p>
<p>Tallymander 2 lets you build chains of equations, called computations. Comps can use any tally as input. They can also use other comps. You build comps with this UI:</p>
<p><a href="http://www.danilocampos.com/wp-content/uploads/2009/10/photo1.jpg"><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="photo" src="http://www.danilocampos.com/wp-content/uploads/2009/10/photo1.jpg" alt="photo" width="320" height="480" /></a>Each step uses the result of the previous step as its first input, lets the user select an operation, then a second input. As each input changes, the result of the computation is updated accordingly. You can even format the final result as a percentage. This kind of data analysis has a lot of benefits, especially for those keeping scores for athletics or tabletop gaming.</p>
<p>I&#8217;m pretty happy with how this came out, with one snag: since there&#8217;s no way to do PEMDAS with this, you need to set up other computations to handle parenthetical parts of a given equation. 3 + (Red roses x <img src='http://blog.danilocampos.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> &#8211; 4, for example, would require the creation of two computations. I think I can solve this by allowing sub-computations that don&#8217;t show up in the many tally list. Something for 2.1</p>
<p>The other big request was the ability to group tallies together.</p>
<p>Done. Set up as many groups as you like. An implementation detail currently means you can&#8217;t move a tally from one group into another. I&#8217;ll find a way around it for 2.1.</p>
<h2>Mission 3: Object Model</h2>
<p>Implicit in any new version of Tallymander was the need to create a proper object model. The Tallymander 1.x model was, and I&#8217;m cringing here, <em>a collection of NSDictionary objects</em> stored to, yeah, <em>NSUserDefaults</em>. C&#8217;mon! This is not how you want to build your object graph, folks. It was an easy way to wrap my mind around the data I needed to store early on. It worked in the beginning but only with much nasty, nasty code.</p>
<p>Luckily, two things happened since I first wrote Tallymander. First, I learned how to build model objects and their relationships by hand. Second, Apple brought <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html">Core Data</a> to the iPhone, which does all that heavy lifting for you. For 2.0, I was ready to do it right.</p>
<p>Joyful. That&#8217;s the only word to describe working with Core Data. It&#8217;s an outstanding, powerful and well documented framework. What would have taken me days to code by hand I can set up in Core Data in one afternoon. I hit an occasional bump or two but always had Stack Overflow to get me back out of the woods. Very glad to have this tool as a developer. 2.0 would have taken a lot longer without it.</p>
<p>But I wasn&#8217;t done with my rickety NSDictionary-based model from 1.x. I got to play with it one last time when I wrote the import code that converted the old data to use the new, shiny model. The worst code is what you wrote eight months ago, I swear it.</p>
<h2>Kitchen sink</h2>
<p>Thanks to Core Data, it was easy to build a pile of new options for tallies. Some of these are customer requests, some are just ideas I had that might be fun.</p>
<p>One of my favorites is the icon picker:</p>
<p><a href="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo3.jpg"><img class="aligncenter size-full wp-image-334" title="photo" src="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo3.jpg" alt="photo" width="320" height="480" /></a>Twirl the wheel to change the icon. There are about fifty to choose from. Of all the UIs I&#8217;ve ever built, this is one of the most fun to use. The icon in the preview at the top updates as the wheel is moved. I like playing with it.</p>
<p>The icons are from the excellent <a href="http://www.glyphish.com">Glyphish</a> collection. Awhile back I contributed to the author&#8217;s <a href="http://www.kickstarter.com/projects/jpwain/awesome-icons-for-your-iphone-apps">Kickstarter project</a>. As a backer, I was rewarded with access to the source vector files that make up the icons. Useful stuff and a great starting point to build Tallymander&#8217;s icon collection. Sadly, Tallymander is <a href="http://spreadsheets.google.com/pub?key=tcQpWLmvqLZ7Egc4m5G9e2w&amp;single=true&amp;gid=0&amp;output=html">not blessed</a> with the Glyphish &#8220;awesome&#8221; designation, but you can&#8217;t win &#8216;em all.</p>
<p>If the built-in icons don&#8217;t strike your fancy, you can insert one from your library, too.</p>
<p>I&#8217;m also liking the color picker:</p>
<p><a href="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo4.jpg"><img class="aligncenter size-full wp-image-335" title="Color Picker" src="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo4.jpg" alt="Color Picker" width="320" height="480" /></a></p>
<p>Another advantage of ditching pre-rendered graphics for the counters: color options galore. I picked some tasteful ones, mostly from Apple&#8217;s Crayon Picker palette.  I like this arrangement better than picking colors off of a list. Everything is visible on the screen at once.</p>
<p>Broke some new ground with custom UI in 2.0. In all, I like how it came out. These are big wins that add a lot to the user&#8217;s ability to make Tallymander their own.</p>
<h2 style="font-size: 1.5em;">Sharing</h2>
<p>The final chunk of functionality that needed to be built was better sharing options. 1.x allowed an email report to be sent from the application. This was decent but with all the new features and depth in 2.0, I wanted to go further.</p>
<p>CSV export ended up being much, much easier than I could have guessed. So that&#8217;s in there, it works and I&#8217;m happy.</p>
<p><a href="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo5.jpg"><img class="aligncenter size-full wp-image-336" title="Tallymander Sharing" src="http://blog.danilocampos.com/wp-content/uploads/2009/10/photo5.jpg" alt="Tallymander Sharing" width="320" height="480" /></a></p>
<p>More exciting is every time I play with the new, full-on sharing feature. Tallymander will let you send your whole setup to someone else.  It&#8217;s a combination of Core Data, Amazon S3 and the <a href="http://allseeing-i.com/ASIHTTPRequest/">ASIHTTPRequest</a> API. ASIHTTPRequest is a superb bit of code. Drop it in, read the docs and you&#8217;re putting and getting data from the web. Stable, easy to understand and an enthusiastic developer at the wheel. Saved me much pain, I&#8217;m certain.</p>
<h2 style="font-size: 1.5em;">And beyond</h2>
<p>So that&#8217;s 2.0. Already I have a mounting list of new refinements and additions I&#8217;d like to make. It&#8217;s a fun app, though, and my proudest yet. Thanks to my enthusiastic customers. I couldn&#8217;t have done 2.0 without your excellent feedback. It was quite a trip: Tallymander 1.2 had about 2,000 lines of code in it. 2.0 has around 8,000 and it&#8217;s a complete rewrite.</p>
<p>I&#8217;m excited to keep tearing into the future of Tallymander and my other apps. As the first full-featured app I&#8217;ve built since going full-time, Tallymander really helped me find my tone and style as an iPhone developer. This stuff is so much fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/10/20/tallymander-2-0-post-mortem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lots of Tally Counters</title>
		<link>http://blog.danilocampos.com/2009/03/20/lots-of-tally-counters/</link>
		<comments>http://blog.danilocampos.com/2009/03/20/lots-of-tally-counters/#comments</comments>
		<pubDate>Sat, 21 Mar 2009 03:52:15 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Musings]]></category>
		<category><![CDATA[Stuff I Like]]></category>
		<category><![CDATA[Stuff that Sucks]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[cocoa touch]]></category>
		<category><![CDATA[tallymander]]></category>
		<category><![CDATA[uikit]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=137</guid>
		<description><![CDATA[Since Tallymander was made a Staff Favorite last month, I&#8217;ve noticed that there are more solutions to the tally problem in the App Store than when I began. There are, of course, many ways to skin a cat. For me, Tallymander does the job best because I built it to my exact desires. Still, while [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-139" title="screenshot-20090217-002257" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/screenshot-20090217-002257.jpg" alt="screenshot-20090217-002257" width="320" height="480" /></p>
<p>Since <a href="http://blog.danilocampos.com/2009/02/17/tallymander-11-available-today/">Tallymander was made a Staff Favorite last month</a>, I&#8217;ve noticed that there are more solutions to the tally problem in the App Store than when I began.</p>
<p>There are, of course, many ways to skin a cat. For me, Tallymander does the job best because <a href="http://blog.danilocampos.com/2009/01/06/oddage-postmortem/">I built it to my exact desires</a>. Still, while many elements of design are subjective, there are good and bad ways to do things. Let&#8217;s look at some of the other approaches to the tally challenge.</p>
<h2>Tally Max</h2>
<p><img class="aligncenter size-medium wp-image-138" title="picture-8" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-8-209x300.png" alt="picture-8" width="209" height="300" /></p>
<p>A few things jump right out:</p>
<p><strong>Inefficient use of space</strong>: The entire width of the iPhone&#8217;s screen is available to each tally cell, but the tally title is confined to a much more limited area. The title is the only element that the user can customize beyond the rails of your design &#8212; give it some room.<span id="more-137"></span></p>
<p><strong>Unfriendly controls</strong>: A good, obvious rule is that the larger a control is, the easier it is to interact with. This is why, for example, the title bar of a window ends up being much larger than the controls to close it. You use the title bar more. It&#8217;s a puzzling choice, then, that Tally Max&#8217;s plus and minus buttons are the same size, since any given counter is likely to flow mostly in one direction. In Tallymander, the entire table view cell is the button. You&#8217;ve got a big, fat, 320 x 60 target to hit to accomplish your task.</p>
<p><strong>Unmotivated interface</strong>: I have a neurotic obsession with LEDs. I have always loved them. That&#8217;s why they appear in pretty much every interface I&#8217;ve ever designed. Tallymander&#8217;s seven-segment counters exist because they&#8217;re readable and because I love how they look. I lovingly built each numerical glyph in Photoshop with the pen tool and spent hours tweaking the glows and highlights for each color. In Tally Max&#8217;s case, the counters are just flat output from a commonly available font. If the author didn&#8217;t want to bother motivating their appearance, why not use a simple text label, like Calculator does, and get a competitive edge from the ability to count beyond 9,999?</p>
<p>Tally Max makes other decisions I don&#8217;t agree with. Tallies are tied to calendar dates and they reset each day, with a record stored for previous days. It also organizes tallies into categories, which could be useful, but puzzlingly, you create new tallies from the Categories view instead of the Tally view. It&#8217;s weird and, ultimately, trying to do too much.</p>
<p>The one inarguably bad bit about Tally Max, though, is this note on its App Store page, screenshot taken 3/20/09:</p>
<p><img class="aligncenter size-full wp-image-140" title="Tally Max 1.0 disclaimer" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-9.png" alt="Tally Max 1.0 disclaimer" width="293" height="66" />That feels like a show-stopper. I would remove my app from sale until that business was resolved.</p>
<h2>Clicker Tally Counter Plus</h2>
<p><img class="aligncenter size-medium wp-image-141" title="picture-10" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-10-209x300.png" alt="picture-10" width="209" height="300" />This app has a terrible name. I&#8217;m fortunate in having a girlfriend whose beauty is matched by an arresting, powerful wit and who comes up with terrific branding to replace my awful project codenames. I sympathize with the challenges involved here. At the same time, the name is very descriptive, so while it gets no points for imagination it will be easily found on the App Store.</p>
<p>The interface is simply gorgeous. I like the aesthetic a great deal, hearkening as it does to chunky, clicky analog gadgets of forgotten days. The font selection is tasteful and motivated to the overall look and feel of the interface. Bang up job.</p>
<p>For me, I sometimes find myself wanting to count multiple things at once. This app doesn&#8217;t address that need especially well, but it&#8217;s still the one I would pick if I had to choose something that wasn&#8217;t Tallymander.</p>
<h2>Counters</h2>
<p><img class="aligncenter size-medium wp-image-142" title="picture-11" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-11-200x300.png" alt="picture-11" width="200" height="300" />Meh. The button lighting isn&#8217;t even consistent.</p>
<h2>Game Keeper Plus</h2>
<p><img class="aligncenter size-medium wp-image-143" title="picture-12" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-12-300x198.png" alt="picture-12" width="300" height="198" /></p>
<p>Game Keeper Plus touts itself as a score keeper, but can do other things:</p>
<p><img class="aligncenter size-full wp-image-144" title="picture-13" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-13.png" alt="picture-13" width="301" height="100" />Hmm, okay. I honestly can&#8217;t figure out how the hell this application works, though. Here&#8217;s another screenshot:</p>
<p><img class="aligncenter size-medium wp-image-145" title="picture-14" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-14-300x199.png" alt="picture-14" width="300" height="199" /></p>
<p>There&#8217;s a bit of backchat about the other apps that are built for keeping scores:</p>
<p><img class="aligncenter size-full wp-image-146" title="picture-15" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-15.png" alt="picture-15" width="301" height="78" />This sales copy explains everything, I think. In trying to do so much, it feels like the developer has overwhelmed himself and the user with&#8230; a whole lot of stuff. Admittedly, Tallymander wasn&#8217;t exactly built with scorekeeping in mind, but for basic game-related tasks I think it does pretty well thanks to a focused, easily-navigated user experience. When you try to do too much, you end up doing too much.</p>
<p>On the subject of doing too much, back to this app being positioned as a stat tracker for non-game related stuff:</p>
<p><img class="aligncenter size-medium wp-image-147" title="picture-16" src="http://blog.danilocampos.com/wp-content/uploads/2009/03/picture-16-200x300.png" alt="picture-16" width="200" height="300" /></p>
<p>That&#8217;s fine; I think everyone here, myself included, isn&#8217;t doing much more than building digital versions of the abacus. Still, with so much game-related terminology baked into the UI, it&#8217;s tough to create a pitch for this app&#8217;s versatility outside the scope of tracking scores. The user ends up having to build a mental translation table between the meaning of the game-related words and whatever custom use they&#8217;ve imagined for themselves.</p>
<p>I don&#8217;t know what the deal is with those eyewatering, heavily aliased pie charts, either.</p>
<h2>The Upshot</h2>
<p>Every problem space has a multitude of ways to approach its solution. This is a great example of that truth. Each of these apps brought different spins to the task of counting things, with varying levels of success. <a href="http://daringfireball.net/2008/11/iphone_likeness">Gruber&#8217;s maxim about iPhone apps</a> is proven once more: <em>Figure out the absolute least you need to do to implement the idea, do just that, and then polish the hell out of the experience.</em></p>
<p>Except for Clicker Tally Counter Plus (say it five times fast), I think each of these apps could probably do with trimming some amount of functionality in favor of making cleaner, more easily navigated experiences. Remember that the iPhone screen is a cramped, tightly-packed place and that mobile users are hasty, impatient people. The less stuff your users have to navigate and the less time they spend having to consider their options, the happier they will be. Functionality and power is good, but it&#8217;s best if you can tuck it away until the last possible moment before the user actually needs it.</p>
<p>On that note, I wonder what I ought to trim from Tallymander.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/03/20/lots-of-tally-counters/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to Get Started as an iPhone Developer</title>
		<link>http://blog.danilocampos.com/2009/02/10/how-to-get-started-as-an-iphone-developer/</link>
		<comments>http://blog.danilocampos.com/2009/02/10/how-to-get-started-as-an-iphone-developer/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 04:40:23 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Decisions]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Stuff I Like]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=114</guid>
		<description><![CDATA[See the 2010 updated edition of this post. Reader Benjamin wrote to me tonight and asked: I have researched some into iPhone programming as I am obsessed with every application that is available for my own iPhone. The problem is that the amount of books and articles out there about programming for an iPhone is [...]]]></description>
			<content:encoded><![CDATA[<p><em>See the 2010 </em><a href="http://blog.danilocampos.com/2010/01/20/iphone-development-for-beginners-2010-edition/"><em>updated edition of this post</em></a><em>.</em></p>
<p><em><br />
</em></p>
<p>Reader Benjamin wrote to me tonight and asked:</p>
<blockquote><p>I have researched some into iPhone programming as I am obsessed with every application that is available for my own iPhone.  The problem is that the amount of books and articles out there about programming for an iPhone is enormous.  Do you have any recommendations for a few killer books to read in order to learn the process/language?</p></blockquote>
<p>What a great question. It&#8217;s one I&#8217;ve been getting a lot from people I know since my apps went on sale.</p>
<p>Thanks to the popularity of the iPhone and the lure of the App Store&#8217;s profit potential, there&#8217;s plenty of crap floating around promising to teach you how to program for this new platform. Much of it sucks. Thankfully, there&#8217;s some gold to be found for iPhone SDK autodidacts. Let&#8217;s check it out.<span id="more-114"></span></p>
<h2><a href="http://en.wikipedia.org/wiki/Computer_science">Wikipedia</a></h2>
<p style="padding-left: 30px;">Say whatever else you want about it, Wikipedia is, unsurprisingly, host to some thorough Computer Science articles. Any time you encounter a term about programming you do not understand, consult Wikipedia. Here are a few examples to get you started:</p>
<p style="padding-left: 30px;"><a href="http://en.wikipedia.org/wiki/Array">Arrays</a></p>
<p style="padding-left: 30px;"><a href="http://en.wikipedia.org/wiki/Control_flow#Loops">Loops</a></p>
<p style="padding-left: 30px;"><a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a>, the design pattern advocated by Apple for iPhone development.</p>
<h2><a href="http://cocoadevcentral.com">Cocoa Dev Central</a></h2>
<p style="padding-left: 30px;">An incredible resource, Cocoa Dev Central hosts some excellent tutorials on Cocoa and Objective-C. It&#8217;s a great place to get started if you don&#8217;t know much and want to learn more.</p>
<h3 style="padding-left: 30px;"><a href="http://cocoadevcentral.com/articles/000081.php" target="_blank">C Tutorial</a></h3>
<p style="padding-left: 30px;">If you know nothing about programming, the C Tutorial is a great way to break yourself in gently. You&#8217;ll get the basics that will become your best friends throughout your work as programmer.</p>
<h3 style="padding-left: 30px;"><a href="http://cocoadevcentral.com/d/learn_objectivec/" target="_blank">Objective-C Tutorial </a></h3>
<p style="padding-left: 30px;">Once you&#8217;ve done the C tutorial and you understand why it works, the Objective-C tutorial is a tidy intro to Objective-C, which is the programming language you&#8217;ll be using for much of your iPhone development.</p>
<p style="padding-left: 30px;">
<h2><a href="http://www.amazon.com/Cocoa-Programming-Mac-OS-3rd/dp/0321503619/ref=pd_lpo_k2_dp_k2a_3_img?pf_rd_p=304485601&amp;pf_rd_s=lpo-top-stripe-2&amp;pf_rd_t=201&amp;pf_rd_i=0321213149&amp;pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_r=1ACZRQ92T84Y551C6AAR">Cocoa Programming for Mac OS X</a></h2>
<p style="text-align: left; padding-left: 30px;"><a href="http://www.amazon.com/Cocoa-Programming-Mac-OS-3rd/dp/0321503619/ref=pd_lpo_k2_dp_k2a_3_img?pf_rd_p=304485601&amp;pf_rd_s=lpo-top-stripe-2&amp;pf_rd_t=201&amp;pf_rd_i=0321213149&amp;pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_r=1ACZRQ92T84Y551C6AAR"><img class="aligncenter" title="Cocoa Programming for Mac OS X" src="http://a2.vox.com/6a00c225270d0a8fdb00fad6954eaa0005-500pi" alt="" width="302" height="400" /></a>After spending some time doing online tutorials, you&#8217;ll want to know whether or not you want to keep doing this. If the answer is yes, Aaron Hillegass&#8217; excellent book is for you. You&#8217;ll learn about Objective-C and the Cocoa API. This is all translatable to the iPhone, as the iPhone SDK uses many similar frameworks and conventions in the Cocoa Touch API. About midway through, you&#8217;ll start hitting some material on desktop-specific technologies like Core Data. Once you&#8217;re at that point, it&#8217;s time to move on to&#8230;</p>
<p style="text-align: left;">
<h2 style="text-align: left;"><a href="http://www.amazon.com/Beginning-iPhone-Development-Exploring-SDK/dp/1430216263/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1234326322&amp;sr=1-1">Beginning iPhone Development</a></h2>
<p style="text-align: center; padding-left: 30px;"><a href="http://www.amazon.com/Beginning-iPhone-Development-Exploring-SDK/dp/1430216263/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1234326322&amp;sr=1-1"><img class="aligncenter" title="Beginning iPhone Development" src="http://ecx.images-amazon.com/images/I/41LV4D3yU6L.jpg" alt="" width="302" height="400" /></a></p>
<p style="text-align: left; padding-left: 30px;">Beginning iPhone Development is accessible and friendly. Assuming you&#8217;re comfortable with what you learned in the previous resources, this book is a snap. Helpful, digestible tutorials and plenty of useful code for use in your own applications. This book covers every single thing you&#8217;ll need to get most apps up, rolling and submitted to the App Store.</p>
<h2 style="text-align: left;">Other Resources</h2>
<p style="padding-left: 30px;">This is by no means an exhaustive or complete list of the great resources out there for iPhone development. This is just what worked for me. Once registered through Apple&#8217;s developer program, you&#8217;ll also have access to developer forums. That community is indispensable and will help you around countless, seemingly insurmountable blocks.</p>
<h2 style="text-align: left;">Bringing it Together</h2>
<p style="padding-left: 30px;"><em>Holy crap</em>, you&#8217;re thinking. <em>That&#8217;s a lot to read and absorb, Danilo.</em> It is indeed. It takes some time, especially if you&#8217;re starting from scratch. Be patient with yourself. This may be the steepest learning curve you&#8217;ll ever encounter as an autodidact.</p>
<p style="padding-left: 30px;">For me, I started Danilo&#8217;s Programming School. That was a commitment to myself that for one to two hours every night of the week, I would work through a tutorial or scribble notes from important subjects in previous chapters. After about two months, I hit a point of epiphany and suddenly the code was a breathing, friendly, understandable creature instead of an inscrutable block of text.</p>
<p style="padding-left: 30px;">This only works if you commit to learning it consistently. It&#8217;s quite literally another language and another mode of thinking.</p>
<p style="padding-left: 30px;">The results, like seeing your first product cough to life after compiling, or customers writing you because they love your work, are incredibly satisfying. If you want to bring a product into the world with your own two hands, nothing is more satisfying right now than building it for the iPhone.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/02/10/how-to-get-started-as-an-iphone-developer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Lure of Best</title>
		<link>http://blog.danilocampos.com/2009/01/31/the-lure-of-best/</link>
		<comments>http://blog.danilocampos.com/2009/01/31/the-lure-of-best/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 18:25:58 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Musings]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[self-indulgent]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=106</guid>
		<description><![CDATA[I do not know why anything works. English, electronics, cooking, driving, name anything. In middle school, when it was time to learn about subjects, predicates and all those other sentence diagramming miseries, I got some of my worst grades ever. Writing was definitely my strongest suit at that point, but when it came to understanding [...]]]></description>
			<content:encoded><![CDATA[<p>I do not know why anything works. English, electronics, cooking, driving, name anything. In middle school, when it was time to learn about subjects, predicates and all those other sentence diagramming miseries, I got some of my worst grades ever. Writing was definitely my strongest suit at that point, but when it came to understanding why writing worked the way it did, I was hopeless.</p>
<p>The reason for this is because I function almost entirely on intuition. I&#8217;m the ultimate learn-by-doing kind of person because the theoretical substance of any given thing is simply not something I am capable of grasping without considerable effort. With repeated exposure to many books and magazines, for example, I knew how a sentence should flow and what words belonged where. I didn&#8217;t know why. I could just sense the rightness or wrongness of the details.</p>
<p>This quality of existence is a curse in school since the bulk of studies rely on the absorbtion of theories or factoids. In a world where results matter, though, intuition serves me well. I make many mistakes in the process, but intuition lets me accomplish a great deal with minimal starting information. It also means I can fix any configuration of technology, short of breaking out a soldering iron (although even then, sometimes).</p>
<p>So it goes with usability. I don&#8217;t actually know what makes for good application usability, beyond obvious things like button size/placement and readable text. I do know what feels right, though, and more importantly, I know what feels very wrong. When I build an interface, it usually starts out pretty wrong. I beat on it and beat on it until all the suck goes away and I <em>sense</em> that it&#8217;s what it should be.</p>
<p>This is work. I can&#8217;t muster the effort to do it without a very specific lure: I need to know that the resulting product has a shot at being the best at what it does. This made <a href="http://www.tallymander.com">Tallymander</a> in particular very seductive: the competing products were so shockingly awful, both in appearance and usability, that all I had to do was apply love and attention to my own solution and I could easily ship the very best counting app in the whole store.</p>
<p>I have a hole in my soul. A deep, ragged, sagging, gaping wound in the very core of my being. The only way I know to fill this hole is to provide exceptionally good solutions to whatever problems I encounter. This makes product design an obvious vocation for me. (Incidentally, it also makes me a brutally effective salesman when I&#8217;m aligned with an array of products I love.)</p>
<p>Today I got this review in the UK App Store:</p>
<blockquote><p>5 Stars</p>
<p><strong>Very useful, well made. </strong></p>
<p>I tried other counting programs and this one came out on top because of :</p>
<p>- Ability to count multiple things at once.</p>
<p>- Email feature.</p>
<p>- Ability to label subjects.</p>
<p>- Nice, pleasingÂ  interface.</p>
<p>A polished program. Thankyou.</p></blockquote>
<p>I didn&#8217;t build Tallymander because I thought it would be a blockbuster moneymaker. I built it because I knew someone, somewhere needed to count things, just like I do. When that someone went searching for a solution to that problem, I wanted Tallymander to satisfy their need without annoying them or worse: leaving them with the nagging feeling that something about it could have been done much better. For a customer in the UK, I seem to have made that magic happen. Even if I made not another cent off of Tallymander, it has done what I hoped for it.</p>
<p>With that pleasant surprise, the wound in my soul heals a little further.</p>
<p>Time to get crackin&#8217; on 1.1.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/01/31/the-lure-of-best/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tallymander is in the App Store</title>
		<link>http://blog.danilocampos.com/2009/01/30/tallymander-is-in-the-app-store/</link>
		<comments>http://blog.danilocampos.com/2009/01/30/tallymander-is-in-the-app-store/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 14:39:54 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[tallymander]]></category>
		<category><![CDATA[uikit]]></category>
		<category><![CDATA[uitableview]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=93</guid>
		<description><![CDATA[I would be remiss if I did not mention that Tallymander has passed Apple&#8217;s scrutiny and made it into the App Store. Visit tallymander.com for the official minisite or check out the iTunes Store Page. Screenshots:]]></description>
			<content:encoded><![CDATA[<p>I would be remiss if I did not mention that Tallymander has passed Apple&#8217;s scrutiny and made it into the App Store. Visit <a href="http://www.tallymander.com">tallymander.com</a> for the official minisite or check out the <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=303492366&amp;mt=8">iTunes Store Page</a>.</p>
<p>Screenshots:</p>
<p style="text-align: center;">
<div id="attachment_94" class="wp-caption aligncenter" style="width: 330px"><img class="size-full wp-image-94" title="Tallymander counts my Drycleaning" src="http://blog.danilocampos.com/wp-content/uploads/2009/01/img_00471.jpg" alt="Tallymander: The original use case" width="320" height="480" /><p class="wp-caption-text">Tallymander: The original use case</p></div>
<div id="attachment_98" class="wp-caption aligncenter" style="width: 330px"><img class="size-full wp-image-98" title="Tally Editing UI" src="http://blog.danilocampos.com/wp-content/uploads/2009/01/img_0065.jpg" alt="You can easily edit tally parameters." width="320" height="480" /><p class="wp-caption-text">Tally parameters</p></div>
<div id="attachment_97" class="wp-caption aligncenter" style="width: 330px"><img class="size-full wp-image-97" title="Motion-enabled row" src="http://blog.danilocampos.com/wp-content/uploads/2009/01/img_0062.jpg" alt="A childhood obsession with bar LEDs manifests itself in every UI I've made for the last four years." width="320" height="480" /><p class="wp-caption-text">A childhood obsession with bar LEDs manifests itself in almost every UI I&#39;ve made for the last four years.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/01/30/tallymander-is-in-the-app-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tallymander shipped</title>
		<link>http://blog.danilocampos.com/2009/01/25/tallymander-shipped/</link>
		<comments>http://blog.danilocampos.com/2009/01/25/tallymander-shipped/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 02:03:28 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[tallymander]]></category>
		<category><![CDATA[uikit]]></category>
		<category><![CDATA[uitableview]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=82</guid>
		<description><![CDATA[After spending the first few years of my career slaving six hours a month on laundry and ironing, I did a cost/benefit analysis and decided that dry cleaning is a better deal. The only chores involved with dry cleaning are gathering your clothes, counting your articles and driving them to the shop. The business of [...]]]></description>
			<content:encoded><![CDATA[<p>After spending the first few years of my career slaving six hours a month on laundry and ironing, I did a cost/benefit analysis and decided that dry cleaning is a better deal. The only chores involved with dry cleaning are gathering your clothes, counting your articles and driving them to the shop.</p>
<p>The business of counting always sucks for me &#8212; I get distracted and lose count. Pen and paper are out of the question for this task, since I need at least one hand free. I figured that someone had already solved my problem in the App Store. I was right:</p>
<div id="attachment_83" class="wp-caption aligncenter" style="width: 268px"><img class="size-full wp-image-83" title="A tally counting app" src="http://blog.danilocampos.com/wp-content/uploads/2009/01/picture-6.png" alt="Fugly Tally App" width="258" height="384" /><p class="wp-caption-text">My competition</p></div>
<p style="text-align: left;">For $6.99, that lovely application could be mine.</p>
<p>Hell no.</p>
<p>Naturally, this meant I was going to have to write my own. I took on the challenge of solving the tally problem in the most flexible, effective way possible. I wasn&#8217;t going to write just a tallying application. I was going to write the <em>killer</em> tally app.</p>
<p><a href="http://www.tallymander.com">Tallymander</a> is a UITableView-based tally manager. You can count up, you can count down. You can count as many different things as you like. You don&#8217;t even have to touch the screen: entries can be set up to respond to a firm shake of your iPhone. You can use it to count things, to keep score, whatever. It has swipe-delete. My favorite feature: you can email a report containing all of your tally data.</p>
<p><img class="aligncenter size-full wp-image-84" title="img_0047" src="http://blog.danilocampos.com/wp-content/uploads/2009/01/img_0047.jpg" alt="img_0047" width="320" height="480" />The interface was inspired by the alarm tab of the Clock app, which I love. Clock is a perfect example of how UITableView is the most badass interface scaffold ever.</p>
<p>I submitted Tallymander for App Store review tonight. It&#8217;s a good palette cleanser, having just shipped <a href="http://oddageapp.com">Oddage</a>. I don&#8217;t want to turn into casual iPhone game programming guy. It&#8217;s also a fun experiment in usability, trying to balance power and flexibility with fun and ease of use.</p>
<p>Is it the <em>killer</em> iPhone tally app? We&#8217;ll see how it goes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2009/01/25/tallymander-shipped/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bank of America: Your iPhone App Sucks</title>
		<link>http://blog.danilocampos.com/2008/09/28/bank-of-america-your-iphone-app-sucks/</link>
		<comments>http://blog.danilocampos.com/2008/09/28/bank-of-america-your-iphone-app-sucks/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 00:13:15 +0000</pubDate>
		<dc:creator>Danilo Campos</dc:creator>
				<category><![CDATA[Improvements]]></category>
		<category><![CDATA[Mediocrity]]></category>
		<category><![CDATA[Stuff that Sucks]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.danilocampos.com/?p=26</guid>
		<description><![CDATA[I know you have a lot on your mind lately, what with your bank purchases and the whole of the finance industry falling apart. Still, I'd like to inspire your engineers to embark upon a simple, fun skunkworks project.]]></description>
			<content:encoded><![CDATA[<p>Dear BofA:</p>
<p>I know you have a lot on your mind lately, what with your bank purchases and the whole of the finance industry falling apart. Still, I&#8217;d like to inspire your engineers to embark upon a simple, fun skunkworks project.</p>
<p>You may remember cashing in the iPhone App Store craze with your free BofA app this summer. You did promise to make it less ugly. You haven&#8217;t followed through yet.</p>
<p>Now, we&#8217;re all busy and I sympathize. Making a nice app is hard. So I did the hard part and designed a UI for you. It&#8217;s a gift. Repay me by implementing it and sparing us all the hideous orgy of Times New Roman that is your existing iPhone UI.</p>
<p>Remember, I&#8217;ve done the heavy lifting. This isn&#8217;t hard. You don&#8217;t even need to do it in Cocoa. You can keep using the WebKit display your app currently uses and implement my design in <a href="http://daringfireball.net/2007/06/wwdc_2007_keynote">John Gruber&#8217;s &#8220;shit sandwich.&#8221;</a></p>
<p>Now, the existing home screen is okay.</p>
<p style="text-align: center;"><img class="aligncenter" title="Home" src="http://blog.danilocampos.com/assets/2008/09/IMG_0008.PNG" alt="" width="256" height="384" /></p>
<p style="text-align: left;">It&#8217;s when we actually want to get down to some banking that things go downhill:</p>
<p style="text-align: center;"><img class="aligncenter" title="Login" src="http://blog.danilocampos.com/assets/2008/09/IMG_0009.PNG" alt="" width="256" height="384" /><img class="aligncenter" title="Sitekey" src="http://blog.danilocampos.com/assets/2008/09/IMG_0010.PNG" alt="" width="256" height="384" /></p>
<p style="text-align: center;"><a href="http://blog.danilocampos.com/assets/2008/09/img_0009.png"></a><span style="color: #551a8b; text-decoration: underline;"><br />
</span></p>
<p style="text-align: left;">Wow. That&#8217;s a lot of Times. Ugly, small, hard to read. Fix it like this:</p>
<p style="text-align: center;"><img class="aligncenter" title="Login" src="http://blog.danilocampos.com/assets/2008/09/Login-to-Online-Banking.gif" alt="" width="246" height="368" /></p>
<p style="text-align: center;"><img class="aligncenter" title="Sitekey" src="http://blog.danilocampos.com/assets/2008/09/Verify-Sitekey.gif" alt="" width="246" height="368" /></p>
<p style="text-align: left;">Next, let&#8217;s get logged in:</p>
<p style="text-align: center;"><img class="aligncenter" title="Ugly Main Menu" src="http://blog.danilocampos.com/assets/2008/09/IMG_0012.PNG" alt="" width="256" height="384" /></p>
<p style="text-align: left;">Blegh. Let&#8217;s get a tab bar going. Not just because tab bars are handy, which they are, but because making the user tap an area as tiny as those menu links is just cruel to iPhone users:</p>
<p style="text-align: center;"><img class="aligncenter" title="Accounts View" src="http://blog.danilocampos.com/assets/2008/09/Accounts.gif" alt="" width="256" height="384" /></p>
<p style="text-align: left;">There we are. The tab buttons are much easier to strike with a fingertip &#8212; less time wasted by hitting the wrong selection. We&#8217;ll start the user at the accounts breakdown, since your balance is almost always the info you want first. Next, let&#8217;s check out account detail:</p>
<p style="text-align: center;"><img class="aligncenter" title="Ugly Account Detail" src="http://blog.danilocampos.com/assets/2008/09/IMG_0013.PNG" alt="" width="256" height="384" /></p>
<p style="text-align: left;">Painful. Let&#8217;s better group the transaction information and use some visual cues to explain individual entries:</p>
<p style="text-align: center;"><img class="aligncenter" title="Account Detail" src="http://blog.danilocampos.com/assets/2008/09/Account-Detail.gif" alt="" width="256" height="384" /></p>
<p style="text-align: left;">Not so hard. You already use those icons for desktop online banking. Now let&#8217;s transfer funds:</p>
<p style="text-align: center;"><img class="aligncenter" title="Bad Transfer" src="http://blog.danilocampos.com/assets/2008/09/IMG_0014.PNG" alt="" width="256" height="384" /><img class="aligncenter" title="Transfer amount" src="http://blog.danilocampos.com/assets/2008/09/IMG_0015.PNG" alt="" width="256" height="384" /></p>
<p style="text-align: left;">Making the user step through multiple screens for a single task sucks, especially in 2008. Let&#8217;s streamline this:</p>
<p style="text-align: center;"><img class="aligncenter" title="Transfer Funds UI" src="http://blog.danilocampos.com/assets/2008/09/Transfer-Funds.gif" alt="" width="256" height="384" /></p>
<p style="text-align: center;">
<p style="text-align: left;">Better! The user doesn&#8217;t lose track of what&#8217;s going on.</p>
<p style="text-align: left;">Nothing crazy, here, just some simple suggestions based on existing iPhone UI conventions. I hope this helps you guys.</p>
<p style="text-align: left;">
<p style="text-align: left;"><em>I built these mockups using the excellent <a href="http://www.teehanlax.com/blog/?p=447">iPhone UI PSD file</a>. The payroll information above is speculative. I do not work for Apple. Yet.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilocampos.com/2008/09/28/bank-of-america-your-iphone-app-sucks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->