Dumb Mistakes

iOS – TableView Row Height Wrong on 64-bit Only

I had a fun little problem pop up at my client site today. We had a tableview that was displaying data that looked perfect when running on everything except for an iPhone 5s. After a little bit of DuckDuckGo-ing, we came across these Stack Overflow questions here and here that suggested that the heightForRowAtIndexPath method might be the culprit.

When I went and dug in, I found this warning (I did do some cut and paste to get the warning just over near the code):

float to CGFloat Warning

If you can’t read it, that warning says, “Conflicting return type in implementation of ‘tableView:heightForRowAtIndexPath:’: ‘CGFloat’ (aka ‘double’) vs ‘float'”

The code was the following:

- (float) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row % 2 == 0) {
        return 247.0;
    }
    else {
        return 315.0;
    }
}

The signature for that method means that the code should have looked like this:

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row % 2 == 0) {
        return 247.0;
    }
    else {
        return 315.0;
    }
}

So what is the explanation? Basically CGFloat was typedef’ed as float. However, Apple wanted you to use CGFloat in case they ever changed what a CGFloat was going to stand for. Apparently, with the move to 64-bit, Apple has done just that. In 32 bit versions, the signatures were identical. However, now in 64-bit land, because the method was returning the wrong type, iOS considered the return value to be 0, breaking our layout. By only changing the return type in the signature to the proper value, the app functioned again properly.

Keep this in mind the next time you might think about being smarter than the language designers and consider not using their typedefs.

Leave a Reply

Your email address will not be published. Required fields are marked *