UITableView com cabeçalhos de seção fixa

107

Saudações, estou lendo que o comportamento padrão de UITableViewé fixar as linhas do cabeçalho da seção no topo da tabela conforme você rola pelas seções até que a próxima seção empurre a linha da seção anterior para fora da vista.

Tenho um UITableViewdentro de a UIViewControllere não parece ser o caso.

Esse é apenas o comportamento padrão para UITableViewController?

Aqui está um código simplificado com base no que eu tenho. Mostrarei a UIControllerinterface e cada método de visualização de tabela que implementei para criar a visualização de tabela. Eu tenho uma classe de fonte de dados auxiliar que me ajuda a indexar meus objetos para uso com a tabela.

    @interface MyUIViewController ()<UITableViewDelegate, UITableViewDataSource>
        @property (nonatomic, readonly) UITableView *myTableView;
        @property (nonatomic, readonly) MyCustomHelperDataSource *helperDataSource;
    @end

    //when section data is set, get details for each section and reload table on success
    - (void)setSectionData:(NSArray *)sections {
        super.sectionData = sections; //this array drives the sections

        //get additional data for section details
        [[RestKitService sharedClient] getSectionDetailsForSection:someId 
        success:^(RKObjectRequestOperation *operation, RKMappingResult *details) {
            NSLog(@"Got section details data");
            _helperDataSource = [[MyCustomHelperDataSource alloc] initWithSections:sections andDetails:details.array];
            [myTableView reloadData];
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"Failed getting section details");
        }];
    }

    #pragma mark <UITableViewDataSource, UITableViewDelegate>

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        if (!_helperDataSource) return 0;
        return [_helperDataSource countSectionsWithDetails]; //number of section that have details rows, ignore any empty sections
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        //get the section object for the current section int
        SectionObject *section = [_helperDataSource sectionObjectForSection:section];
        //return the number of details rows for the section object at this section
        return [_helperDataSource countOfSectionDetails:section.sectionId];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        UITableViewCell * cell;

        NSString *CellIdentifier = @"SectionDetailCell";

        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
            cell.textLabel.font = [UIFont systemFontOfSize:12.0f];
        }

        //get the detail object for this section
        SectionObject *section = [_helperDataSource sectionObjectForSection:indexPath.section]; 

        NSArray* detailsForSection = [_helperDataSource detailsForSection:section.sectionId] ;
        SectionDetail *sd = (SectionDetail*)[detailsForSection objectAtIndex:indexPath.row];

        cell.textLabel.text = sd.displayText;
        cell.detailTextLabel.text = sd.subText;
        cell.detailTextLabel.textColor = [UIColor blueTextColor];

        return cell;
    }

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 50.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 30.0f;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger) section {
    //get the section object for the current section
    SectionObject *section = [_helperDataSource sectionObjectForSection:section]; 

    NSString *title = @"%@ (%d)";

    return [NSString stringWithFormat:title, section.name, [_helperDataSource countOfSectionDetails:section.sectionId]];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 0)];
    header.autoresizingMask = UIViewAutoresizingFlexibleWidth;

    header.backgroundColor = [UIColor darkBackgroundColor];

    SSLabel *label = [[SSLabel alloc] initWithFrame:CGRectMake(3, 3, 260, 24)];
    label.font = [UIFont boldSystemFontOfSize:10.0f];
    label.verticalTextAlignment = SSLabelVerticalTextAlignmentMiddle;
    label.backgroundColor = [UIColor clearColor];
    label.text = [self tableView:tableView titleForHeaderInSection:section];
    label.textColor = [UIColor whiteColor];
    label.shadowColor = [UIColor darkGrayColor];
    label.shadowOffset = CGSizeMake(1.0, 1.0);
    [header addSubview:label];

    return header;
}
Topwik
fonte
Isso deve funcionar. Mostre algum código.
Matthias Bauch
Essa é uma maneira totalmente boa de usar um UITableView e deve funcionar com os cabeçalhos. O que os cabeçalhos não estão fazendo no seu caso?
Eric
@Eric os cabeçalhos rolam com as linhas. Eles não param no topo da mesa enquanto eu rolo. Eu adicionei o código que estou usando para gerar minha visualização de tabela. É um UITableView dentro de um UIViewController.
topwik

Respostas:

305

Os cabeçalhos só permanecem fixos quando a UITableViewStylepropriedade da tabela é definida como UITableViewStylePlain. Se você tiver definido como UITableViewStyleGrouped, os cabeçalhos rolarão para cima com as células.

Bachonk
fonte
3
meu estilo tableview é UITableViewStylePlain, mas também rola para cima com as células.
yudun1989
8
Existem algumas explicações possíveis para isso. Uma observação importante é que os cabeçalhos só permanecerão fixos para células dentro de sua seção. Portanto, se você tiver um cabeçalho na seção 0, ele não permanecerá fixo para as células na seção 1. Outra explicação possível é que você não está inicializando seu UITableView com o estilo adequado. É recomendável que você use initWithStyle:UITableViewStylePlain, pois chamar algo como tableView.style = UITableViewStylePlain não funcionará.
bachonk
UITableViewStyleGrouped torna o cabeçalho / rodapé fixo com outras células, enquanto UITableViewStylePlain torna o cabeçalho / rodapé "flutuante" quando o cabeçalho / rodapé atinge a parte superior / inferior do tableview.
StoneLam
@bachonk estou usando uma visualização de cabeçalho extensível. e meu estilo é UITableViewStyleGrouped. quero corrigir o cabeçalho ao rolar para cima. se eu torná-lo UITableViewStylePlain, o cabeçalho está sendo corrigido no meio da tela, eu quero rolar o cabeçalho para baixo, mas ao rolar para cima, quero que ele seja corrigido na primeira linha ... será possível?
Desenvolvedor Gorib
3

Altere seu estilo de TableView:

self.tableview = [[UITableView alloc] initwithFrame: estilo do quadro: UITableViewStyleGrouped];

De acordo com a documentação da apple para UITableView:

UITableViewStylePlain- Uma visão de tabela simples. Quaisquer cabeçalhos ou rodapés de seção são exibidos como separadores embutidos e flutuam quando a visualização da tabela é rolada.

UITableViewStyleGrouped- Uma visão de tabela cujas seções apresentam grupos distintos de linhas. Os cabeçalhos e rodapés da seção não flutuam.

Espero que esta pequena mudança ajude você ..

Aks
fonte
2
isso parece ser exatamente o oposto do que a pergunta solicitada - deveria ser Plain, nãoGrouped
CupawnTae
1

Swift 3.0

Criar um ViewController com as UITableViewDelegate e UITableViewDataSource protocolos. Em seguida, crie um tableView dentro dele, declarando seu estilo como UITableViewStyle.grouped . Isso corrigirá os cabeçalhos.

lazy var tableView: UITableView = {
    let view = UITableView(frame: UIScreen.main.bounds, style: UITableViewStyle.grouped)
    view.delegate = self
    view.dataSource = self
    view.separatorStyle = .none
    return view
}()
Nursultan Askarbekuly
fonte
0

Você também pode definir a propriedade bounces do tableview como NO. Isso manterá os cabeçalhos da seção não flutuantes / estáticos, mas você também perderá a propriedade bounce do tableview.

Kevinl
fonte
0

para fazer com que o cabeçalho das seções UITableView não seja aderente ou aderente:

  1. mude o estilo da visualização da tabela - torne-a agrupada para não ser fixa e torne-a simples para cabeçalhos de seção fixas - não se esqueça: você pode fazer isso a partir do storyboard sem escrever código. (clique na visualização da mesa e altere seu estilo no menu lateral / componente direito)

  2. se você tiver componentes extras, como visualizações personalizadas ou etc., verifique as margens da visualização da tabela para criar o design apropriado. (como altura do cabeçalho para seções e altura da célula no caminho do índice, seções)

Burcu Kutluay
fonte
-2

Agora seu tableview se parece com o estilo de tabela simples, mas não flutue com o estilo de tabela de configuração definido para grupo.

[_tableView setBackgroundView:nil];
_tableView.backgroundColor = [UIColor whiteColor];
Ravi Kumar
fonte