iPhone Development: Force UITableView to show only complete cells

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.

Partially visible cells vs. Fully Visible Cells

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 Post-Mortem

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…


SwedeShop

I remember the first time I went to IKEA.

It blew my brain open. It’s the coolest retail experience in the history of the world.

There’s only one problem: you gotta keep track of a lot of data if you want to get out of there with everything you wanted to take home.

Enter SwedeShop, my unofficial IKEA shopping list app. Find out more at the main site:

http://www.danilocampos.com/apps/swedeshop/


The Gravest Pain of an iPhone Developer

It’s a chattery time for App Store problems. Apple rejected Google Voice, then neutered Ninjawords and still presents an utterly opaque face to developers.

There are a laundry list of problems facing the growth of the App Store. I won’t bother to rehash them here. Let’s focus on the one that most thoroughly jeopardizes the future of developer businesses: Customer Service. Every other problem can be overcome or worked around but without the power of caring for your customers, your business has no reason to exist.

In an aside to a link last month, John Gruber muses:

I’m wondering how much of the problem is that the App Store is built on the foundation and framework of the iTunes Music Store, which was designed from the outset specifically as a venue for selling 99-cent downloads.

This is the most crucially important point: the iTunes Store was never designed to sell software. Among other things, Craig Hockenberry enumerates all the ways in which the App Store is hobbled by this historical truth. It’s a good, important post that you should read if you care about this kind of stuff. But it doesn’t address long-term outcomes related to customer service that will doom the developer community.

As an iPhone developer, I have no control over my storefront – Apple manages it for me, with basic data I provide. On the one hand, this is incredible news: access to a huge pool of customers, a complete distribution infrastructure and – best of all – I never have to worry about payment processing.

There’s just one issue: Apple doesn’t give a damn about my relationship with my customers.

Generous, attentive, impassioned customer service is an important piece of any successful business. My customers mean the world to me. Unfortunately, iTunes does not provide a clear, encouraging feedback channel.

User Reviews

When you’re selling music, user reviews are a simple tool. Much is subjective, but overall quality will be reflected in the reviews.

With software, the reviews have become more complicated. The most tantalizing way for a customer to speak out about software that is giving them problems is to write a review. And that’s what they do. Bug reports, feature requests and anything else that comes into their minds gets dumped into the reviews. And why not? The ability to write a review is prominently featured and uses a built-in, official form. It’s infinitely more seductive than leaving iTunes to write an email to the support contact. It’s also a venue provided by the same service that is taking the customer’s money, so it feels more intimately linked to their purchase than anything they can do on an external website or in their email client.

This is infuriating since the communication is strictly one-sided. There’s no way for the developer to follow up on these reviews to ask for more information. Without that information, acting on a bug report is often impossible. The worst part is that without dialogue, it’s impossible for the customer to learn more about their problem, discover workarounds and discover that there’s a living, breathing person who truly cares about the quality of the software they’ve just purchased.

Like it or not, the iTunes user review becomes the support form of last resort.

The Consequence

There are ways around this. Tap4Help is an interesting example, providing a built-in feedback and support request system. Developers, like Lucius Kwok, report some success explicitly declaring their email right in their application description with a call to action encouraging its use. I do this, too, but it doesn’t catch them all.

Why not? Nothing will ever come close to the power and authority of iTunes itself. I theorize that part of the reason so many customers prefer the review form to using a support email or link is that they know that iTunes will provide them satisfaction. No matter what, iTunes will show their review. They will be heard.

By keeping these customers so thoroughly at arm’s length, Apple retards the formation of relationships that will build developers’ business. I’ve turned angry emails into loyal customers through the power of honesty and genuine interest in customer issues. I’d desperately love to provide that dialogue for every customer, ever, but iTunes, under the current system, will continue to siphon off some portion of those opportunities into its black hole of customer reviews.

Having good conversations with your customers is as essential and non-negotiable as having an engine in your car. When Zappos tweets at me in thanks for my praise, I feel as though my relationship with the company has been further validated. When Netflix gives me complete and generous support when I have trouble with their service, I feel respect for them, since their conduct conveys respect for my business.

It’s all about how the customer feels. If you never get to talk with them, you’ll never get to impact that feeling.

Let’s Do It Better

This is not a hard problem to solve. If you happen to work on the iTunes Store infrastructure team, you may feel differently, but the company you work for is in the business of accomplishing the impossible on a fairly regular basis. My sympathy is limited.

Developer Review Replies

This is the easiest part. Let the developer reply to user reviews. This isn’t groundbreaking and I’m the eight thousandth developer to suggest it. So make it happen. The developer can join the conversation and solicit additional information so that bug reports that go into the reviews can actually be productive. Notify whomever left the review that they have a response via email. For bonus points, let the customer reply directly to that notification to reach the developer.

Feedback/Support Form

Let the user provide feedback or support requests through an official, iTunes-embedded form. Send the feedback to the developer via email, with an anonymized reply-to address, like craigslist uses, so Apple can cover their ass on privacy concerns. For bonus points, provide a rating for each application that states how responsive each developer is to requests sent via this form.

There is no step three. With those two provisions, an open dialogue has been created for anyone who bothers to seek one. Software, even for the iPhone, is not music. The one-sided echo-chamber conversation of the iTunes Music Store does not work in the App Store. With the two modest tools I’ve described, developers will have an infinitely easier time creating the relationships they need to build their business.

I’m not going to hold my breath. Hopefully Apple is working on this stuff, but in the meantime, I need to figure out better ways to put myself in easy reach of my customers.


Whew

GlobeJot is back.


Next

Prev