Alterando o tamanho da fonte dos cabeçalhos de seção UITableView

138

Alguém pode me instruir sobre a maneira mais fácil de alterar o tamanho da fonte do texto em um cabeçalho da seção UITableView?

Eu tenho os títulos das seções implementados usando o seguinte método:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

Então, eu entendo como alterar com êxito a altura do cabeçalho da seção usando este método:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

Eu tenho as células UITableView preenchidas usando este método:

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

No entanto, estou empolgado em saber como realmente aumentar o tamanho da fonte - ou, nesse caso, o estilo da fonte - do texto do cabeçalho da seção?

Alguém pode ajudar? Obrigado.

JRD8
fonte
1
Swift versão
Juan Boero

Respostas:

118

Infelizmente, talvez você precise substituir isso:

No Objetivo-C:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

Em Swift:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?

Tente algo como isto:

No Objetivo-C:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UILabel *myLabel = [[UILabel alloc] init];
    myLabel.frame = CGRectMake(20, 8, 320, 20);
    myLabel.font = [UIFont boldSystemFontOfSize:18];
    myLabel.text = [self tableView:tableView titleForHeaderInSection:section];

    UIView *headerView = [[UIView alloc] init];
    [headerView addSubview:myLabel];

    return headerView;
}

Em Swift:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let myLabel = UILabel()
    myLabel.frame = CGRect(x: 20, y: 8, width: 320, height: 20)
    myLabel.font = UIFont.boldSystemFont(ofSize: 18)
    myLabel.text = self.tableView(tableView, titleForHeaderInSection: section)

    let headerView = UIView()
    headerView.addSubview(myLabel)

    return headerView
}
mosca1337
fonte
1
Obrigado. Isso funcionou perfeitamente. Muito apreciado.
JRD8
5
Embora essa seja uma solução correta, tenha cuidado com este método. Para um cabeçalho com mais de uma linha, você terá que executar os cálculos da altura do cabeçalho em tableView:heightForHeaderInSection:que pode ser complicado.
Leo Natan
3
Tentei isso e, embora funcione se você rolar a tabela para cima, o Rótulo do cabeçalho permanece na tela e sobrepõe as células. :(
Plasma
2
@ Trss Acho que você encontrará esse comportamento não esperado. Eu não estou falando sobre a seção de cabeçalho ficar lá, apenas o rótulo, e é super imposto às células quando elas passam por baixo, fazendo com que pareça uma verdadeira bagunça. Eu encontrei uma maneira melhor de conseguir isso e vou publicá-la novamente quando a encontrar novamente.
Plasma
1
@ mosca1337 não há necessidade de criar outra visualização, é possível exibir o 'UITableViewHeaderFooterView' real e ajustar os parâmetros.
Juan Boero 07/07
367

Outra maneira de fazer isso seria responder ao UITableViewDelegatemétodo willDisplayHeaderView. A visão passada é na verdade uma instância de a UITableViewHeaderFooterView.

O exemplo abaixo altera a fonte e também centraliza o texto do título na vertical e na horizontal na célula. Observe que você também deve responder para heightForHeaderInSectionque as alterações na altura do cabeçalho sejam contabilizadas no layout da exibição da tabela. (Ou seja, se você decidir alterar a altura do cabeçalho neste willDisplayHeaderViewmétodo.)

Você pode responder ao titleForHeaderInSectionmétodo para reutilizar esse cabeçalho configurado com diferentes títulos de seção.

Objetivo-C

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;

    header.textLabel.textColor = [UIColor redColor];
    header.textLabel.font = [UIFont boldSystemFontOfSize:18];
    CGRect headerFrame = header.frame;
    header.textLabel.frame = headerFrame;
    header.textLabel.textAlignment = NSTextAlignmentCenter;
}

Swift 1.2

(Nota: se o seu controlador de exibição é descendente de a UITableViewController, isso precisaria ser declarado como override func.)

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
{
    let header:UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView

    header.textLabel.textColor = UIColor.redColor()
    header.textLabel.font = UIFont.boldSystemFontOfSize(18)
    header.textLabel.frame = header.frame
    header.textLabel.textAlignment = NSTextAlignment.Center
}

Swift 3.0

Esse código também garante que o aplicativo não trava se a visualização do cabeçalho for algo diferente de um UITableViewHeaderFooterView:

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }
    header.textLabel?.textColor = UIColor.red
    header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18)
    header.textLabel?.frame = header.frame
    header.textLabel?.textAlignment = .center
}
Mark Semsel
fonte
3
Este método funcionou muito melhor para mim do que o descrito acima
Plasma
6
Melhor resposta que eu já vi.
Phatmann # 6/14
2
Essa seria a maneira "correta" de ajustar as informações, assumindo que não há outro motivo para subclassificar (como adicionar visualizações, por exemplo). Além disso, esse método pode ser usado para atualizar o texto do cabeçalho do Tipo dinâmico. Basta usar: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];e / ou header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];juntamente com os outros passos necessários (ver aqui: captechconsulting.com/blog/john-szumski/... )
Leanne
3
Isso não redimensiona a exibição do cabeçalho; portanto, se sua fonte for maior ou significativamente diferente, como o Zapfino (não pergunte o porquê), ele cortará o texto. Se você precisar calcular o tamanho por conta própria, é uma bagunça e não deve fazê-lo.
Leo Natan
@CocoaPriest Não está travando na minha versão beta, tho. (Seed GM 2)
Patrick Bassut
96

Embora a resposta de mosca1337 seja uma solução correta, tenha cuidado com esse método. Para um cabeçalho com texto com mais de uma linha, você terá que executar os cálculos da altura do cabeçalho em tableView:heightForHeaderInSection:que pode ser complicado.

Um método muito preferido é usar a API de aparência:

[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setFont:[UIFont boldSystemFontOfSize:28]];

Isso mudará a fonte, enquanto ainda sai da tabela para gerenciar as alturas em si.

Para obter melhores resultados, subclasse a visualização de tabela e adicione-a à cadeia de contenção (pol appearanceWhenContainedIn:) para garantir que a fonte seja alterada apenas para as visualizações de tabela específicas.

Leo Natan
fonte
1
Se subclassificar, você retornaria uma visualização personalizada da - tableView:viewForHeaderInSection:direita? Nesse caso, a fonte pode ser definida ali. É isso que a solução da @ mosca1337 faz de qualquer maneira.
trss
1
Haha, bem, eu sou um woozey depois de ontem. Subclasse a exibição de tabela e adicione-a à lista de contêineres. ;-)
Leo Natan
2
Esta solução causa muitos erros no cálculo do tamanho real do rodapé / cabeçalho. Eu posso mostrar alguns exemplos quando os títulos são cortados enquanto a fonte personalizada está configurada.
kas-kad
5
Swift 3 :UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
Eric Hodgins
3
Isso não redimensiona o rótulo corretamente para caber na fonte no iOS 11. Além disso, a rolagem para cima e para baixo após o carregamento das exibições as redefine para a fonte padrão.
Nickdnk 5/09
25

Para o iOS 7, eu uso isso,


-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;

    header.textLabel.font = [UIFont boldSystemFontOfSize:10.0f];
    header.textLabel.textColor = [UIColor orangeColor];
}

Aqui está a versão Swift 3.0 com redimensionamento de cabeçalho

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let header = view as? UITableViewHeaderFooterView {
        header.textLabel!.font = UIFont.systemFont(ofSize: 24.0)
        header.textLabel!.textColor = UIColor.orange          
    }
}
Maria
fonte
6
Isso não dimensionará a exibição do cabeçalho para caber na nova fonte.
Leo Natan
@LeoNatan Como podemos dimensionar a visualização do cabeçalho para se ajustar à nova fonte - isso pode ser feito neste método?
SAHM
Queria esclarecer que vi sua resposta acima, mas só quero alterar a fonte para limitar o tamanho quando uma fonte selecionada pelo usuário (acessibilidade) excede um determinado tamanho (portanto, não o tempo todo). Acredito que preciso verificar e possivelmente alterar a fonte no willDisplayHeaderView, então existe uma maneira de eu recalcular a altura da exibição se a fonte for alterada?
SAHM
19

Swift 3:

Maneira mais simples de ajustar apenas o tamanho:

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

    let header = view as! UITableViewHeaderFooterView

    if let textlabel = header.textLabel {
        textlabel.font = textlabel.font.withSize(15)
    }
}
jeff-ziligy
fonte
Essa é a maneira mais fácil que eu estou procurando.
21718 Ryan
Funciona em 4 velozes! Não se esqueça "override func .."
Matvey
8

Swift 2.0 :

  1. Substitua o cabeçalho da seção padrão por UILabel totalmente personalizável.

Implemente viewForHeaderInSection, da seguinte maneira:

  override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let sectionTitle: String = self.tableView(tableView, titleForHeaderInSection: section)!
    if sectionTitle == "" {
      return nil
    }

    let title: UILabel = UILabel()

    title.text = sectionTitle
    title.textColor = UIColor(red: 0.0, green: 0.54, blue: 0.0, alpha: 0.8)
    title.backgroundColor = UIColor.clearColor()
    title.font = UIFont.boldSystemFontOfSize(15)

    return title
  }
  1. Altere o cabeçalho padrão (mantém o padrão).

Implemente o willDisplayHeaderView, da seguinte maneira:

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

    if let view = view as? UITableViewHeaderFooterView {
      view.backgroundView?.backgroundColor = UIColor.blueColor()
      view.textLabel!.backgroundColor = UIColor.clearColor()
      view.textLabel!.textColor = UIColor.whiteColor()
      view.textLabel!.font = UIFont.boldSystemFontOfSize(15)
    }
  }

Lembre-se: se você estiver usando células estáticas, o primeiro cabeçalho da seção será mais alto que os demais, devido à parte superior do UITableView; para corrigir isso:

Implemente heightForHeaderInSection, da seguinte maneira:

  override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    return 30.0 // Or whatever height you want!
  }
Elliott Davies
fonte
4

A versão Swift 4 da resposta de Leo Natan é

UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)

Se você quiser definir uma fonte personalizada, poderá usar

if let font = UIFont(name: "font-name", size: 12) {
    UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = font
}
Giorgio
fonte
Infelizmente, isso não redimensiona o quadro.
nickdnk
3

Com esse método, você também pode definir o tamanho da fonte, o estilo da fonte e o fundo do cabeçalho . existem dois métodos para isso

Primeiro método

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section{
        UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
        header.backgroundView.backgroundColor = [UIColor darkGrayColor];
        header.textLabel.font=[UIFont fontWithName:@"Open Sans-Regular" size:12];
        [header.textLabel setTextColor:[UIColor whiteColor]];
    }

Segundo método

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
//    myLabel.frame = CGRectMake(20, 8, 320, 20);
    myLabel.font = [UIFont fontWithName:@"Open Sans-Regular" size:12];
    myLabel.text = [NSString stringWithFormat:@"   %@",[self tableView:FilterSearchTable titleForHeaderInSection:section]];

    myLabel.backgroundColor=[UIColor blueColor];
    myLabel.textColor=[UIColor whiteColor];
    UIView *headerView = [[UIView alloc] init];
    [headerView addSubview:myLabel];
    return headerView;
}
Anup Gupta
fonte
1

Swift 2:

Conforme solicitado pelo OP, apenas ajuste o tamanho, não configurando-o como uma fonte em negrito do sistema ou o que for:

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        if let headerView = view as? UITableViewHeaderFooterView, textLabel = headerView.textLabel {

            let newSize = CGFloat(16)
            let fontName = textLabel.font.fontName
            textLabel.font = UIFont(name: fontName, size: newSize)
        }
    }
Juan Boero
fonte
0

Esta é a minha solução com o Swift 5.

Para controlar totalmente a visualização da seção do cabeçalho, você precisa usar o método tableView (: viewForHeaderInsection: :) no seu controlador, como mostrou a postagem anterior. No entanto, há uma etapa adicional: para melhorar o desempenho, a Apple recomenda não gerar uma nova visualização sempre, mas reutilizar a visualização do cabeçalho, assim como reutilizar a célula da tabela. Isso é feito pelo método tableView.dequeueReusableHeaderFooterView (withIdentifier:). Mas o problema que tive foi quando você começou a usar essa função de reutilização, a fonte não funcionará conforme o esperado. Outras coisas como cor, alinhamento, tudo bem, mas apenas fonte. Existem algumas discussões, mas eu fiz funcionar da seguinte maneira.

O problema é tableView.dequeueReusableHeaderFooterView (withIdentifier :) não é como tableView.dequeneReuseCell (:), que sempre retorna uma célula. O primeiro retornará um valor zero se não houver ninguém disponível. Mesmo que ele retorne uma exibição de cabeçalho de reutilização, não é o tipo de classe original, mas um UITableHeaderFooterView. Então você precisa fazer o julgamento e agir de acordo com seu próprio código. Basicamente, se for nulo, obtenha uma nova exibição de cabeçalho. Se não for nulo, force a conjuração para poder controlar.

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let reuse_header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "yourHeaderID")
        if (reuse_header == nil) {
            let new_sec_header = YourTableHeaderViewClass(reuseIdentifier:"yourHeaderID")
            new_section_header.label.text="yourHeaderString"
            //do whatever to set color. alignment, etc to the label view property
            //note: the label property here should be your custom label view. Not the build-in labelView. This way you have total control.
            return new_section_header
        }
        else {
            let new_section_header = reuse_section_header as! yourTableHeaderViewClass
            new_sec_header.label.text="yourHeaderString"
            //do whatever color, alignment, etc to the label property
            return new_sec_header}

    }
JerryH
fonte