É possível desativar os cabeçalhos flutuantes no UITableView com UITableViewStylePlain?

177

Estou usando um UITableView'layout' para o conteúdo do layout. Estou usando os cabeçalhos da exibição de tabela para fazer o layout de certas imagens, etc., e eu preferiria que elas não flutuassem, mas permanecessem estáticas como quando o estilo está definido UITableViewStyleGrouped.

Além de usar UITableViewStyleGrouped, existe uma maneira de fazer isso? Eu gostaria de evitar o uso agrupado, pois adiciona uma margem abaixo de todas as minhas células e requer a desativação da exibição em segundo plano de cada uma das células. Eu gostaria de ter controle total do meu layout. Idealmente, eles seriam "UITableViewStyleBareBones", mas eu não vi essa opção nos documentos ...

Muito Obrigado,

Complicado
fonte
59
Use o estilo de tabela UITableViewStyleGrouped - esta é a resposta para todos os que procuram desabilitar cabeçalhos flutuantes e não leem a pergunta toda (aconteceu comigo ...).
Média Joe
@ Kasztan Esta é uma solução de linha zero que funciona muito bem! Obrigado.
Lee Fastenau 13/03/2015

Respostas:

27

Você poderá fingir isso usando uma célula personalizada para fazer as linhas do cabeçalho. Eles serão rolados como qualquer outra célula na exibição da tabela.

Você só precisa adicionar alguma lógica cellForRowAtIndexPathpara retornar o tipo de célula correto quando for uma linha de cabeçalho.

Você provavelmente terá que gerenciar suas seções sozinho, ou seja, ter tudo em uma seção e falsificar os cabeçalhos. (Você também pode tentar retornar uma exibição oculta para a exibição do cabeçalho, mas não sei se isso funcionará)

frankodwyer
fonte
11
Sim ... parece um pouco complicado, no entanto. Isso parece uma supervisão da parte da Apple, pois claramente o código existe para isso, basta ser capaz de definir uma sinalização.
Tricky
2
Verifique minha resposta abaixo para a maneira correta de obter o efeito sem nenhum corte especial, basta gerenciar a primeira célula de cada seção como seu cabeçalho!
Sumit Anantwar
338

Uma maneira provavelmente mais fácil de conseguir isso:

Objetivo-C:

CGFloat dummyViewHeight = 40;
UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, dummyViewHeight)];
self.tableView.tableHeaderView = dummyView;
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0);

Rápido:

let dummyViewHeight = CGFloat(40)
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0)

Os cabeçalhos de seção agora rolam como qualquer célula normal.

samvermette
fonte
5
Este friggin funciona como um encanto !! A presença de um cabeçalho de exibição de cabeçalho da tabela impede que os cabeçalhos da seção flutuem. E um cabeçalho invisível com inserções de conteúdo apropriadas para a tabela faz o truque. Muito obrigado! perguntar por que esta resposta não está recebendo muita atenção
Shyam Bhat
4
Ainda não acredito nisso! Sem APIs privadas, sem aprofundar as classes, nada! Venho enfrentando esse problema há muito tempo e adicionando visualizações de tabelas na parte superior das visualizações de rolagem (com a rolagem de visualização desativada), o que faria com que os cabeçalhos da tabela rolassem normalmente. mas comecei a pesquisar se a Apple forneceu novos métodos recentemente para corrigir isso .. estou tão feliz por ter encontrado sua resposta. obrigado novamente
Shyam Bhat
13
a única desvantagem que vi é que o cabeçalho superior não será mais exibido (você pode vê-lo apenas através da rolagem para cima). Pelo menos para mim ele não é mostrado
Ruzard
5
Você ainda pode mostrar o tableHeaderView da tabela aumentando sua altura na parte superior, em um número igual à altura do cabeçalho da seção e reduzindo o conteúdo inserido no mesmo número.
Shyam Bhat
2
Eu gostaria de poder votar novamente, tenho certeza de que é a terceira vez que acabo com essa pergunta e isso resolveu meu problema.
amigos estão dizendo sobre
252

(Para quem já chegou aqui devido ao estilo de tabela incorreto) Altere o estilo da tabela de comum para agrupado, por meio do inspetor de atributos ou por código:

let tableView = UITableView(frame: .zero, style: .grouped)
david72
fonte
3
Era exatamente isso que eu estava procurando. Obrigado!
Ninjudd 02/12/19
4
"Além de usar UITableViewStyleGrouped, existe uma maneira de fazer isso?"
Michael Peterson
27
Boa coisa que eu aprendi a verificar todas as respostas antes de implementar o mais upvoted :)
Tung Fam
1
Agora esse pessoal, é a resposta que você estava procurando. Esteja ciente de que você também pode encontrar a TableView Stylepropriedade no AttributesInspector.
Cristian Holdunu
4
A pergunta menciona especificamente procurar uma maneira "Outros que não sejam UITableViewStyleGrouped"
Ferdz 15/01/19
73

AVISO : esta solução implementa um método de API reservado. Isso pode impedir que o aplicativo seja aprovado pela Apple para distribuição na AppStore.

Eu descrevi os métodos particulares que alternam os cabeçalhos de seção flutuando no meu blog

Basicamente, você só precisa subclassificar UITableViewe retornar NOem dois de seus métodos:

- (BOOL)allowsHeaderViewsToFloat;
- (BOOL)allowsFooterViewsToFloat;
calço
fonte
40
Uma resposta não merece voto negativo apenas porque faz referência a APIs privadas (nem todo mundo está escrevendo o código a ser enviado à AppStore). Isso é duplamente verdadeiro quando a resposta está correta. Subclassificar (ou, mais facilmente, criar uma categoria UITableView) que retorna NO para esses métodos impede que os cabeçalhos flutuem. Se você gostaria de ver este adicionado como uma API pública, por favor envie um relatório de bug: bugreport.apple.com
jemmons
5
Se implementarmos essa função em um aplicativo, como a Apple perceberá que você está usando uma API privada? Pelo que eles sabem, acabei de implementar um método em uma subclasse do UITableView, e eles nem conseguem ver isso sem desmontar o código, e isso não seria tão fácil. Não está chamando um método em uma API privada, é só implementar um ....
Javier Soto
3
@jemmons se você não quiser que eu diminua o seu voto, marque-o como "API privada é usada aqui". Tipo de exoneração de responsabilidade :)
kas-kad
2
O link do "meu blog" está quebrado
MartinMoizard
12
@jemmons "nem todo mundo está escrevendo um código para ser enviado à AppStore" A Appstore não é realmente o problema. O problema é que a apple pode alterar as APIs privadas sem se comunicar ou descontinuar o que interromperá seu aplicativo. Essa é uma razão melhor para você não usar APIs privadas do que ser rejeitado pela Apple
aryaxt
29

Ok, eu sei que é tarde, mas eu tive que fazê-lo. Eu já passei 10 horas procurando uma solução funcional, mas não encontrei uma resposta completa. Encontrou algumas dicas, mas é difícil para os iniciantes entenderem. Então eu tive que colocar meus 2 centavos e completar a resposta.

Como foi sugerido nas poucas respostas, a única solução de trabalho que consegui implementar é inserir células normais na exibição da tabela e manipulá-las como cabeçalhos de seção, mas a melhor maneira de alcançá-la é inserindo essas células em linha 0 de cada seção. Dessa forma, podemos lidar com esses cabeçalhos não flutuantes personalizados com muita facilidade.

Então, os passos são.

  1. Implemente UITableView com o estilo UITableViewStylePlain.

    -(void) loadView
    {
        [super loadView];
    
        UITableView *tblView =[[UITableView alloc] initWithFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height-44-61-frame.origin.y) style:UITableViewStylePlain];
        tblView.delegate=self;
        tblView.dataSource=self;
        tblView.tag=2;
        tblView.backgroundColor=[UIColor clearColor];
        tblView.separatorStyle = UITableViewCellSeparatorStyleNone;
    }
  2. Implemente titleForHeaderInSection como de costume (você pode obter esse valor usando sua própria lógica, mas eu prefiro usar delegados padrão).

    - (NSString *)tableView: (UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        NSString *headerTitle = [sectionArray objectAtIndex:section];
        return headerTitle;
    }
  3. Implementar numberOfSectionsInTableView como de costume

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    {
        int sectionCount = [sectionArray count];
        return sectionCount;
    }
  4. Implemente numberOfRowsInSection como de costume.

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    {
        int rowCount = [[cellArray objectAtIndex:section] count];
        return rowCount +1; //+1 for the extra row which we will fake for the Section Header
    }
  5. Retorne 0,0f em heightForHeaderInSection.

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 0.0f;
    }
  6. NÃO implemente viewForHeaderInSection. Remova o método completamente em vez de retornar nulo.

  7. Em heightForRowAtIndexPath. Verifique se (indexpath.row == 0) e retorne a altura da célula desejada para o cabeçalho da seção, caso contrário, retorne a altura da célula.

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row == 0)
        {
            return 80; //Height for the section header
        }
        else
        {
            return 70; //Height for the normal cell
        }
    }
  8. Agora, em cellForRowAtIndexPath, verifique se (indexpath.row == 0) e implemente a célula como deseja que o cabeçalho da seção seja e defina o estilo de seleção como none. ELSE implementa a célula como deseja que seja a célula normal.

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SectionCell"];
            if (cell == nil)
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SectionCell"] autorelease];
                cell.selectionStyle = UITableViewCellSelectionStyleNone; //So that the section header does not appear selected
    
                cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SectionHeaderBackground"]];
            }
    
            cell.textLabel.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:indexPath.section];
    
            return cell;
        }
        else
        {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    
            if (cell == nil) 
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease];
                cell.selectionStyle = UITableViewCellSelectionStyleGray; //So that the normal cell looks selected
    
                cell.backgroundView =[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellBackground"]]autorelease];
                cell.selectedBackgroundView=[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SelectedCellBackground"]] autorelease];
            }
    
            cell.textLabel.text = [[cellArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row -1]; //row -1 to compensate for the extra header row
    
            return cell;
        }
    }
  9. Agora implemente willSelectRowAtIndexPath e retorne nulo se indexpath.row == 0. Isso cuidará para que didSelectRowAtIndexPath nunca seja acionado para a linha de cabeçalho da Seção.

    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            return nil;
        }
    
        return indexPath;
    }
  10. E, finalmente, em didSelectRowAtIndexPath, verifique se (indexpath.row! = 0) e continue.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row != 0)
        {
            int row = indexPath.row -1; //Now use 'row' in place of indexPath.row
    
            //Do what ever you want the selection to perform
        }
    }

Com isso você está pronto. Agora você tem um cabeçalho de seção não flutuante e perfeitamente rolante.

Sumit Anantwar
fonte
1
Implementado 'willSelectRowAtIndexPath' para que o controle nunca atinja 'didSelectRowAtIndexPath' ao selecionar a linha do cabeçalho da seção.
precisa saber é o seguinte
Na verdade, eu dobrei + desdobro as linhas quando o cabeçalho é selecionado. Mas é bom saber que você pode fazer isso
Yariv Nissim
Ótima resposta, mas por que o 'if (indexPath.row! = 0)' registrou 'didSelectRowAtIndexPath'? É apenas para ser mais seguro? A linha nunca pode ser 0 com a implementação 'willSelectRowAtIndexPath', certo?
precisa saber é o seguinte
1
@ Glenn85, desculpe pela resposta tardia. Sim, é apenas para uma segurança extra.
Sumit Anantwar
28

No seu Interface Builder, clique no seu problema. Table View

visualização da tabela de problemas

Em seguida, navegue até o Attributes Inspector e altere Style Plain para Grouped;) Easy

fácil

HannahCarney
fonte
17

O interessante de UITableViewStyleGrouped é que o tableView adiciona o estilo às células e não ao TableView.

O estilo é adicionado como backgroundView às células como uma classe chamada UIGroupTableViewCellBackground, que lida com o desenho de segundo plano diferente de acordo com a posição da célula na seção.

Portanto, uma solução muito simples será usar UITableViewStyleGrouped, defina backgroundColor da tabela como clearColor e substitua simplesmente backgroundView da célula em cellForRow:

cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds] autorelease];
adamsiton
fonte
1
Essa deve ser a resposta principal. Existe uma publicação no blog sobre isso aqui: corecocoa.wordpress.com/2011/09/17/…
Sam
Esta solução realmente não funciona. Continuo recebendo um espaço extra nas células próximas. Qualquer ideia ?
gsempe
2
O contentView das células ainda não seria deslocado para a direita?
Piotr Tomasik 30/10/12
15

Altere seu estilo do TableView:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];

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

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

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

Aks
fonte
5

Existe outra maneira complicada. A idéia principal é dobrar o número da seção, e a primeira mostra apenas o headerView enquanto a segunda mostra as células reais.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return sectionCount * 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section%2 == 0) {
        return 0;
    }
    return _rowCount;
}

O que é necessário fazer é implementar os delegados headerInSection:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        //return headerview;
    }
    return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        //return headerheight;
    }
    return 0;
}

Essa abordagem também tem pouco impacto nas suas fontes de dados:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    int real_section = (int)indexPath.section / 2;
    //your code
}

Comparando com outras abordagens, dessa maneira é seguro, sem alterar o quadro ou as inserções de conteúdo da visualização da tabela. Espero que isso possa ajudar.

faixa
fonte
5

A maneira mais fácil de obter o que deseja é definir o estilo da tabela como UITableViewStyleGrouped, separador como UITableViewCellSeparatorStyleNone:

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN; // return 0.01f; would work same 
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return [[UIView alloc] initWithFrame:CGRectZero];
}

Não tente retornar a visualização do rodapé nil, pois não se esqueça de definir a altura do cabeçalho e a visualização do cabeçalho, depois de obter o que deseja.

Michail Pidgorodetskiy
fonte
4

Embora isso possa não resolver o seu problema, foi o que aconteceu comigo quando quis fazer algo semelhante. Em vez de definir o cabeçalho, usei o rodapé da seção acima. O que me salvou foi que esta seção era pequena e estática por natureza, portanto nunca rolou abaixo da parte inferior da exibição.

Torbjörn
fonte
Boa ideia. Eu amo esse truque.
31812 Steve Moser
meio engraçado. aprecie a ideia, mas um hack é um hack. os cabeçalhos iria começar a flutuar na parte inferior para não resolve realmente o problema
Shyam Bhat
4

Para Swift 3+

Basta usar UITableViewStyleGroupede definir a altura do rodapé para zero com o seguinte:

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return .leastNormalMagnitude
}
Tamás Sengel
fonte
1
Você pode retornar 0 em vez de .leastNormalMagnitude. Também é necessário implementartableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
Ilias Karim
@IliasKarim Definir como 0 faz com que ele tenha uma altura diferente de zero. Além disso, não é necessário implementar a viewForFooterInSectionfunção neste caso.
Tamás Sengel 24/02
0e .leastNormalMagnitudeteve o mesmo efeito. viewForFooterSectionÉ necessário implementar o método. Você deve retornar nulo. Isso está no Swift 5.1 com o Xcode 11.3.1.
Ilias Karim
3

Enquanto pensava em como abordar esse problema, lembrei-me de um detalhe muito importante sobre o UITableViewStyleGrouped. A maneira como o UITableView implementa o estilo agrupado (as bordas arredondadas ao redor das células) é adicionando um backgroundView personalizado ao UITableViewCells, e não ao UITableView. A cada célula é adicionado um backgroundView de acordo com sua posição na seção (as linhas superiores obtêm a parte superior da borda da seção, as do meio obtêm a borda lateral e a inferior fica - bem, a parte inferior). Portanto, se apenas queremos um estilo simples e não temos um backgroundView personalizado para nossas células (que é o caso em 90% das vezes), tudo o que precisamos fazer é usar UITableViewStyleGrouped e remover o fundo personalizado . Isso pode ser feito seguindo estas duas etapas:

Altere nosso estilo tableView para UITableViewStyleGrouped Adicione a seguinte linha ao cellForRow, imediatamente antes de retornar a célula:

cell.backgroundView = [[[alocação de UIView] initWithFrame: cell.bounds] autorelease];

E é isso. O estilo tableView se tornará exatamente como UITableViewStylePlain, exceto os cabeçalhos flutuantes.

Espero que isto ajude!

James Laurenstin
fonte
2

Talvez você possa usar scrollViewDidScrollna mesaVer e alterar ocontentInset base no cabeçalho visível atual.

Parece funcionar para o meu caso de uso!

extension ViewController : UIScrollViewDelegate{

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard   let tableView = scrollView as? UITableView,
            let visible = tableView.indexPathsForVisibleRows,
            let first = visible.first else {
            return
        }

        let headerHeight = tableView.rectForHeader(inSection: first.section).size.height
        let offset =  max(min(0, -tableView.contentOffset.y), -headerHeight)
        self.tableView.contentInset = UIEdgeInsetsMake(offset, 0, -offset, 0)
   }
}
Martin
fonte
1

Outra maneira de fazer isso é criar uma seção vazia antes da que você deseja colocar o cabeçalho e colocá-lo nessa seção. Como a seção está vazia, o cabeçalho rolará imediatamente.

devguydavid
fonte
1

Você pode adicionar uma seção (com zero linhas) acima e definir o sectionFooterView acima como o headerView da seção atual, o footerView não flutua. Espero que ajude.

Lee Lam
fonte
Os FooterViews flutuam, assim como os HeaderViews. Eles apenas flutuam na parte inferior da tela, não na parte superior.
MarkDonohoe
0

Ignore o XAK. Não explore métodos privados se quiser que seu aplicativo seja aceito pela Apple.

Isso é mais fácil se você estiver usando o Interface Builder. Você adicionaria uma UIView na parte superior da visualização (para onde as imagens irão) e, em seguida, adicionaria sua tableview abaixo dela. O IB deve dimensioná-lo adequadamente; ou seja, a parte superior da tableview toca a parte inferior da UIView que você acabou de adicionar e a altura cobre o restante da tela.

O pensamento aqui é que, se esse UIView não for realmente parte da visualização da tabela, ele não será rolado com a visualização da tabela. ou seja, ignore o cabeçalho do tableview.

Se você não estiver usando o construtor de interface, é um pouco mais complicado, pois é necessário obter o posicionamento e a altura corretos para a visualização da tabela.

imnk
fonte
Isso não responde à pergunta. Tricky está se referindo ao titleHeaderViews, que são as visualizações que ficam entre as células, não à visualização do cabeçalho da tabela, que você sugere.
Daniel Madeira
0

Verifique a resposta de como implementar cabeçalhos com o StoryBoard: Exibições de cabeçalho da tabela no StoryBoards

Observe também que, se você não implementar

viewForHeaderInSection:(NSInteger)section

não flutuará, exatamente o que você deseja.

Raphael Oliveira
fonte
0

Para remover completamente as seções do cabeçalho da seção flutuante, faça o seguinte:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return [[UIView alloc] init];
}

return nil não funciona

Para desativar a flutuação, mas ainda mostrar os cabeçalhos das seções, você pode fornecer uma exibição personalizada com seus próprios comportamentos.

djskinner
fonte
0

Uma variação na solução do @ samvermette:

/// Allows for disabling scrolling headers in plain-styled tableviews
extension UITableView {

    static let shouldScrollSectionHeadersDummyViewHeight = CGFloat(40)

    var shouldScrollSectionHeaders: Bool {
        set {
            if newValue {
                tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: bounds.size.width, height: UITableView.shouldScrollSectionHeadersDummyViewHeight))
                contentInset = UIEdgeInsets(top: -UITableView.shouldScrollSectionHeadersDummyViewHeight, left: 0, bottom: 0, right: 0)
            } else {
                tableHeaderView = nil
                contentInset = .zero
            }
        }

        get {
            return tableHeaderView != nil && contentInset.top == UITableView.shouldScrollSectionHeadersDummyViewHeight
        }
    }

}
raf
fonte
0

O trecho exibe um cabeçalho fixo apenas para a primeira seção. Outros cabeçalhos de seção flutuam com células.

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    if section == 1 {
        tableView.contentInset = .zero
    }

}

func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
    if section == 0 {
        tableView.contentInset = .init(top: -tableView.sectionHeaderHeight, left: 0, bottom: 0, right: 0)
    }
}
Adobels
fonte
-1

Isso pode ser conseguido atribuindo a exibição do cabeçalho manualmente no método viewDidLoad do UITableViewController em vez de usar o viewForHeaderInSection e heightForHeaderInSection do delegado. Por exemplo, na sua subclasse de UITableViewController, você pode fazer algo assim:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 40)];
    [headerView setBackgroundColor:[UIColor magentaColor]];
    [headerView setTextAlignment:NSTextAlignmentCenter];
    [headerView setText:@"Hello World"];
    [[self tableView] setTableHeaderView:headerView];
}

A visualização do cabeçalho desaparecerá quando o usuário rolar. Não sei por que isso funciona assim, mas parece alcançar o que você deseja fazer.

Johnny Oshika
fonte
Isso não é para uma seção, é para um cabeçalho na parte superior.
makdad
-1

Talvez você possa simplesmente tornar transparente o plano de fundo da visualização do cabeçalho:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    view.tintColor = [UIColor clearColor];
}

Ou aplique-o globalmente:

    [UITableViewHeaderFooterView appearance].tintColor = [UIColor clearColor];
Tinpont
fonte
-2

Eu tenho outra solução ainda mais simples, para ser usada sem autolayout e com tudo feito através do XIB:

1 / Coloque seu cabeçalho na tableview arrastando e soltando-o diretamente na tableview.

2 / No Inspetor de tamanho do cabeçalho recém-fabricado, basta alterar o tamanho automático: você deve deixar apenas as âncoras superior, esquerda e direita, além do preenchimento horizontalmente.

É assim que deve ser definido para o cabeçalho

Isso deve fazer o truque!

CyberDandy
fonte
-2

De acordo com a resposta de @ samvermette, eu implementei o código acima no Swift para facilitar o uso rápido dos codificadores.

let dummyViewHeight = CGFloat(40)
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0)
Bingerz
fonte
-2

ref: https://stackoverflow.com/a/26306212

let tableView = UITableView(frame: .zero, style: .grouped)

PLUSE

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return 40
    }else{
        tableView.sectionHeaderHeight = 0
    }

    return 0
}

Isso ajudou a usar o espaço do cabeçalho

Pratik
fonte
Por favor, não faça isso🙏
MQoder 20/03/19
-3

Atualização mais recente de 2020

Testado com o Xcode 14.

Para ocultar qualquer cabeçalho da seção, Retornar nulo para o título do delegado da seção

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return nil
}
Saranjith
fonte
-4

você pode conseguir isso facilmente implementando o método viewForHeaderInSection na classe de delegado tableview. esse método espera um UIView como objeto de retorno (que é sua visualização de cabeçalho). eu fiz a mesma coisa no meu código

Raj
fonte
O pôster original não deseja um cabeçalho personalizado. Eles querem um cabeçalho que não "flutue" na parte superior da tabela. Sua sugestão ainda flutua.
jemmons
mudar o tableview para UITableViewStyleGrouped com viewforheader, então ele vai fazê-lo parar
mskw