iosobjective-cuitableviewcocoa-touchuilocalizedcollation

How does `sectionForSectionIndexTitleAtIndex` on UILocalizedIndexCollation work? (Esp with custom section titles) It always returns the same number


Is this different in different locales? I'm completely failing to understand what the point of the sectionForSectionIndexTitleAtIndex method on UILocalizedIndexCollation is. Every index I pass just returns the identical index.

The documentation is not very helpful at all, and I can't seem to find any instance where the number it returns is different than the number I supply it. Why not just return the number itself?

Worse, if I add additional indices to my table view, such as UITableViewIndexSearch and some custom ones, so that in total my table view's section index titles have the search character, two custom ones, letters of the alphabet and # (for a total of 30 section titles), I have no idea what to pass into sectionForSectionIndexTitleAtIndex from UITableViewDataSource's sectionForSectionIndexTitle:atIndex: method!

If I pass the index the table view method gives me (say 1), it'll give me 1 back, which is wrong, because if I tap on the section index 1, it should jump to the first custom one. So I should only start once the alphabet part starts, which starts at section index 3. But if I pass 3 into the sectionForSectionIndexTitleAtIndex method, I get 3 back, when I should be getting 2 back, because the search character isn't an actual section.

So I should only start after 3, at which point I subtract 1 to get the actual index. Okay. Then I get to the last section index, the #, at index 29. I pass 29 - 1 (which is 28) to sectionForSectionIndexTitleAtIndex and I then get an error that it's out of the bounds, because there's only 27 characters.

How on earth should I be using it in this case? It seems completely useless, and I feel like just returning the index. But does this break under certain locales? How does this method work?


Solution

  • Let's take a step back and talk about the table view data source method tableView:sectionForSectionIndexTitle:atIndex:.

    The purpose of tableView:sectionForSectionIndexTitle:atIndex: is typically where you are creating sections and section titles (for the index) manually, and you're going to display fewer section titles in the index than there actually are sections.

    Another use is where you are creating section and section titles manually, and you are adding extra section titles in the index. For example, a common convention is to make the first index item a magnifying glass which the user can tap to see the search field at the top of the table view (its header view). Here's an implementation that takes care of that situation:

    - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
        if (index == 0)
            [tableView scrollRectToVisible:tableView.tableHeaderView.frame
                                  animated:NO];
        return index-1;
    }
    

    (If the index is zero, we end up returning -1, which is not a real index, but it does no harm either.)

    With UILocalizedIndexCollation, you are not creating sections and section titles manually: the collation is. You are handing control over to it. You don't know whether the number of section titles will be the same as the number of sections. So you have to provide an implementation of tableView:sectionForSectionIndexTitle:atIndex:, just in case. So you implement tableView:sectionForSectionIndexTitle:atIndex: by asking the collation for its sectionForSectionIndexTitleAtIndex, as shown in the documentation:

    - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
    {
        return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
    }
    

    So the answer to your question, "what the point of the sectionForSectionIndexTitleAtIndex method on UILocalizedIndexCollation is", is: it's so that you can implement tableView:sectionForSectionIndexTitle:atIndex: when you're using a collation. For a particular localized collation, there might be a one to one correspondence between section titles and sections, or there might not; but you don't know and you don't care. Simply do what the boilerplate in the documentation tells you to do, and you'll be fine.