July 14, 2012

Segmented Wordlist Table

I wrote some pretty formerly hairy code to deal with smooth, pretty transitions between the different word lists. It's not that it's transitioning between different tables, it's that the table's rows themselves pop in and out.

Graphically the code does something like this to figure out which rows need to be added and which need to be removed. The canonical, sorted word list (drawn in the center) makes it easier than it otherwise would have been.

I really must stop using isEqualToString: and whatnot in this code!

    int l_index = 0,
        r_index = 0,
        l_sentinel = [oldSelectedWords count],
        r_sentinel = [selectedWords count];

    for (int i = 0; i < count; ++i) {
        NSString *word = [[words objectAtIndex:i] objectAtIndex:0];
        NSString *l_word = nil;
        NSString *r_word = nil;

        if (l_index < l_sentinel) {
            l_word = [[oldSelectedWords objectAtIndex:l_index] objectAtIndex:0];
        }

        if (r_index < r_sentinel) {
            r_word = [[selectedWords objectAtIndex:r_index] objectAtIndex:0];
        }

        if ([word isEqualToString:l_word] && [word isEqualToString:r_word]) {
            /* l = w = r; keep this word */
            l_index++;
            r_index++;
        }
        else if ([word isEqualToString:l_word]) {
            /* l = w =/= r; drop this word */
            [deleteIndexes addObject:[NSIndexPath indexPathForRow:l_index inSection:0]];
            l_index++;
        }
        else if ([word isEqualToString:r_word]) {
            /* l =/= w = r; add this word */
            [insertIndexes addObject:[NSIndexPath indexPathForRow:r_index inSection:0]];
            r_index++;
        }
    }

    [table beginUpdates];
        [table insertRowsAtIndexPaths:insertIndexes withRowAnimation:UITableViewRowAnimationFade];
        [table deleteRowsAtIndexPaths:deleteIndexes withRowAnimation:UITableViewRowAnimationFade];
    [table endUpdates];