21 Jun, 2013 12:24

Criando seções retráteis em iOS

Primeiro passo

No seu projeto, crie uma classe filha de UITableViewController, por exemplo. Implemente normalmente os métodos de datasource da sua tableView. Em nosso exemplo, definimos que a lista tem 3 seções, sendo a primeira seção com 1 célula, a segunda com 2 e a última com 3 células.

Exemplo de lista

Segundo passo

Após a criação da lista, precisamos configurar para que as seções recebam o toque para fazer as células sumirem ou aparecerem. Para isso, implementamos o método (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section da seguinte forma:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
    label.text = [NSString stringWithFormat:@"Seção %d", section+1];
    label.backgroundColor = [UIColor grayColor];

    label.tag = section;
    label.userInteractionEnabled = YES;

    UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(alternarVisibilidadeSecao:)];
    tapped.numberOfTapsRequired = 1;
    [label addGestureRecognizer:tapped];

    return label;
}

Perceba que determinei que toda a vez que a view da seção receber um toque, o método alternarVisibilidadeSecao: será chamado. Abaixo, a mágica.

Terceiro passo

Para fazer a mágica acontecer, o método alternarVisibilidadeSecao deve fazer o seguinte:

// array que descreve se a seção inicialmente está aberta ou fechada
static BOOL secoesVisiveis[3] = {YES, NO, YES};

- (void)alternarVisibilidadeSecao:(UITapGestureRecognizer *)gesture {
    NSInteger section = gesture.view.tag;

    if (secoesVisiveis[section]) {
        NSArray *indexPaths = [self indexPathsDaSecao:section];
        secoesVisiveis[section] = false;

        [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationBottom];
    }
    else {
        secoesVisiveis[section] = true;
        [self.tableView insertRowsAtIndexPaths:[self indexPathsDaSecao:section] withRowAnimation:UITableViewRowAnimationBottom];
    }
}

- (NSArray *)indexPathsDaSecao:(NSInteger)section {
    NSInteger numberOfRows = [self tableView:self.tableView numberOfRowsInSection:section];

    NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:numberOfRows];
    for (int i = 0; i < numberOfRows; i++) {
        [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:section]];
    }

    return indexPaths;
}

O método alternarVisibilidadeSecao basicamente modifica o array, que indica a visibilidade de cada seção. Já o método (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section é que faz a mágica acontecer.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (secoesVisiveis[section])
        switch (section) {
            case IndiceUm:
                return 1;
            case IndiceDois:
                return 2;
            case IndiceTres:
                return 3;
        }

    return 0;
}

Agora é só executar o projeto. O resultado será esse:

Resultado final

O código do exemplo se encontra aqui.

Ao navegar neste site, você consente o uso de cookies nossos e de terceiros, que coletam informações anônimas e são essenciais para melhorar sua experiência em nosso site.