Tallymander uses UITableViewCells not only to display data but also to manipulate it. That means that partially-visible cells — that is, those that are cut off at the top or bottom of the view — aren’t terribly useful.
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.
vs. 
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 completely visible. This took a little noodling around with math but it wasn’t hard to do. Put this method into your UITableViewController subclass:
- (void)snapBottomCell
{
NSInteger cellHeight = 62; //Cells for my view are 62px tall. Sub your own height here
NSInteger offsetOverage = (NSInteger) self.tableView.contentOffset.y % cellHeight;
//Use the tableview's contentOffset property and the cell height to determine how much is being cut off
if (offsetOverage > 0)
{
//If the overage is more than 0, we should figure out what the new offset needs to be
NSInteger newOffset;
if (offsetOverage >= (cellHeight/2))
{
newOffset = self.tableView.contentOffset.y + (cellHeight - offsetOverage);
//If the overage is greater than or equal to half the height of a cell, pull the cell up so it's fully visible
}
else {
newOffset = self.tableView.contentOffset.y - offsetOverage;
//Else, push the cell out of view
}
//With the new offset determined, animate the movement:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.tableView setContentOffset:CGPointMake(0, newOffset) animated:NO];
[UIView commitAnimations];
}
}
You’ll need to implement these two delegate methods as well:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self snapBottomCell];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (decelerate == NO)
{
[self snapBottomCell];
}
}
And that’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’s pushed out of view.
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’s height like so:
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:CGPointMake(0, (self.tableView.frame.size.height - 1))];
//Get the index path of the cell currently visible at the bottom edge of the tableview
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self snapBottomCell:cell.frame.size.height];
There are cases where this isn’t useful: long lists whose primary function is selecting data for loading in another view, for example. Still, any time you’re using UITableViewCells to house controls or chunky bits of data, it might be good to ensure that only whole cells are displayed.
Tallymander 2.0 has been in the App Store for a few weeks. Here’s the story on my favorite product, so far.
Once upon a time…
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.
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.
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 GlobeJot 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.
Until one night, around midnight, when I got the “Ready for Sale” email that iPhone developers live for. Tallymander 1.1 was live.
And an App Store Staff Favorite. I peed myself a little. There followed a slew of copycat apps following this prominence. So it goes on the App Store.
The future
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.
Continue Reading…

Since Tallymander was made a Staff Favorite last month, I’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 many elements of design are subjective, there are good and bad ways to do things. Let’s look at some of the other approaches to the tally challenge.
Tally Max

A few things jump right out:
Inefficient use of space: The entire width of the iPhone’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 — give it some room. Continue Reading…
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 enormous. Do you have any recommendations for a few killer books to read in order to learn the process/language?
What a great question. It’s one I’ve been getting a lot from people I know since my apps went on sale.
Thanks to the popularity of the iPhone and the lure of the App Store’s profit potential, there’s plenty of crap floating around promising to teach you how to program for this new platform. Much of it sucks. Thankfully, there’s some gold to be found for iPhone SDK autodidacts. Let’s check it out. Continue Reading…
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.
The reason for this is because I function almost entirely on intuition. I’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’t know why. I could just sense the rightness or wrongness of the details.
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).
So it goes with usability. I don’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 sense that it’s what it should be.
This is work. I can’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 Tallymander 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.
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’m aligned with an array of products I love.)
Today I got this review in the UK App Store:
5 Stars
Very useful, well made.
I tried other counting programs and this one came out on top because of :
- Ability to count multiple things at once.
- Email feature.
- Ability to label subjects.
- Nice, pleasing interface.
A polished program. Thankyou.
I didn’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.
With that pleasant surprise, the wound in my soul heals a little further.
Time to get crackin’ on 1.1.