Cambio del tamaño de fuente para encabezados de sección UITableView

138

¿Alguien puede indicarme la forma más fácil de cambiar el tamaño de fuente para el texto en un encabezado de sección UITableView?

Tengo los títulos de sección implementados usando el siguiente método:

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

Entonces, entiendo cómo cambiar con éxito la altura del encabezado de sección usando este método:

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

Tengo las celdas UITableView pobladas usando este método:

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

Sin embargo, estoy atascado en cuanto a cómo aumentar realmente el tamaño de fuente, o para el estilo de fuente, del texto del encabezado de sección.

¿Alguien puede ayudarme? Gracias.

JRD8
fuente
1
Versión Swift
Juan Boero

Respuestas:

118

Desafortunadamente, es posible que deba anular esto:

En el objetivo-C:

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

En Swift:

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

Intenta algo como esto:

En el 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;
}

En 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
fuente
1
Gracias. Esto funcionó perfectamente. Muy apreciado.
JRD8
55
Si bien esta es una solución correcta, tenga cuidado con este método. Para un encabezado de más de una línea, deberá realizar los cálculos de la altura del encabezado en los tableView:heightForHeaderInSection:que puede ser engorroso.
Leo Natan
3
Intenté esto y, si funciona si desplaza la tabla hacia arriba, la etiqueta de encabezado permanece en la pantalla y superpone las celdas. :(
Plasma
2
@trss Creo que encontrará que este no es un comportamiento esperado. No estoy hablando de que la sección del encabezado permanezca allí, solo la etiqueta, y se superpone a las celdas a medida que pasan debajo, lo que hace que parezca un verdadero desastre. Encontré una mejor manera de lograr esto y lo volveré a publicar una vez que lo encuentre nuevamente.
Plasma
1
@ mosca1337 no hay necesidad de crear otra vista, puede obtener el 'UITableViewHeaderFooterView' real que se muestra y ajustar los parámetros.
Juan Boero
367

Otra forma de hacerlo sería responder al UITableViewDelegatemétodo willDisplayHeaderView. La vista aprobada es en realidad una instancia de a UITableViewHeaderFooterView.

El siguiente ejemplo cambia la fuente y también centra el texto del título vertical y horizontalmente dentro de la celda. Tenga en cuenta que también debe responder para heightForHeaderInSectionque se tengan en cuenta los cambios en la altura de su encabezado en el diseño de la vista de tabla. (Es decir, si decide cambiar la altura del encabezado en este willDisplayHeaderViewmétodo).

Luego, podría responder al titleForHeaderInSectionmétodo para reutilizar este encabezado configurado con diferentes títulos de sección.

C objetivo

- (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: si su controlador de vista es descendiente de a UITableViewController, esto debería declararse 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

Este código también garantiza que la aplicación no se bloquee si su vista de encabezado no es un 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
fuente
3
Este método funcionó mucho mejor para mí que el anterior
plasma
66
La mejor respuesta que he visto.
phatmann
2
Esta sería la forma "adecuada" de ajustar la información, suponiendo que no haya otra razón para la subclase (como agregar vistas, por ejemplo). Además, este método se puede utilizar para actualizar el texto del encabezado para Tipo dinámico. Simplemente use: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];y / o header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];junto con los otros pasos necesarios (consulte aquí: captechconsulting.com/blog/john-szumski/… )
leanne
3
Esto no cambia el tamaño de la vista del encabezado, por lo que si su fuente es más grande o significativamente diferente, como Zapfino (no pregunte por qué), cortará el texto. Si tiene que calcular el tamaño por su cuenta, es un desastre y no debe hacerlo.
Leo Natan
@CocoaPriest No se bloquea en mi versión beta, aunque. (Semilla GM 2)
Patrick Bassut
96

Si bien la respuesta de mosca1337 es una solución correcta, tenga cuidado con ese método. Para un encabezado con texto de más de una línea, deberá realizar los cálculos de la altura del encabezado en los tableView:heightForHeaderInSection:que puede ser engorroso.

Un método muy preferido es usar la API de apariencia:

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

Esto cambiará la fuente, sin dejar la tabla para administrar las alturas.

Para obtener resultados óptimos, subclasifique la vista de tabla y agréguelo a la cadena de contención (in appearanceWhenContainedIn:) para asegurarse de que la fuente solo se cambie para las vistas de tabla específicas.

Leo Natan
fuente
1
Si subclasifica, ¿estaría devolviendo una vista personalizada desde la - tableView:viewForHeaderInSection:derecha? En cuyo caso, la fuente se puede configurar allí mismo. Esto es lo que la solución de @ mosca1337 hace de todos modos.
trss
1
Jaja, bueno, estoy mareado después de ayer. Subclase la vista de tabla y agréguela a la lista de contenedores. ;-)
Leo Natan
2
Esta solución causa muchos errores al calcular el tamaño real del pie de página / encabezado. Puedo mostrar algunos ejemplos cuando los títulos se cortan mientras se configura la fuente personalizada.
kas-kad
55
Swift 3 :UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
Eric Hodgins
3
Esto no cambia el tamaño de la etiqueta correctamente para que se ajuste a la fuente en iOS 11. Además, al desplazarse hacia arriba y hacia abajo después de cargar las vistas, se restablece a la fuente predeterminada.
nickdnk
25

Para iOS 7 uso esto,


-(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];
}

Aquí está la versión Swift 3.0 con cambio de tamaño del encabezado

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
fuente
66
Esto no cambiará el tamaño de la vista del encabezado para que se ajuste a la nueva fuente.
Leo Natan
@LeoNatan ¿Cómo podemos dimensionar la vista del encabezado para que se ajuste a la nueva fuente? ¿Se puede hacer con este método?
SAHM
Quería aclarar que vi su respuesta anterior, pero solo quiero cambiar la fuente para limitar el tamaño cuando la fuente seleccionada por el usuario (accesibilidad) excede cierto tamaño (por lo tanto, no todo el tiempo). Creo que necesito verificar y posiblemente cambiar la fuente en willDisplayHeaderView, entonces, ¿hay alguna manera de que pueda volver a calcular la altura de la vista si se cambia la fuente?
SAHM
19

Swift 3:

La forma más sencilla de ajustar solo el tamaño:

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
fuente
Esa es la forma más fácil que estoy buscando.
Ryan
Funciona en swift 4! No olvide "anular func .."
Matvey
8

Swift 2.0 :

  1. Reemplace el encabezado de sección predeterminado con UILabel totalmente personalizable.

Implemente viewForHeaderInSection, así:

  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. Alterar el encabezado predeterminado (conserva el predeterminado).

Implemente willDisplayHeaderView, así:

  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)
    }
  }

Recuerde: si usa celdas estáticas, el primer encabezado de sección se rellena más alto que otros encabezados de sección debido a la parte superior de UITableView; para arreglar esto:

Implemente heightForHeaderInSection, así:

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

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

La respuesta de Swift 4 de Leo Natan es:

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

Si desea establecer una fuente personalizada, puede usar

if let font = UIFont(name: "font-name", size: 12) {
    UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = font
}
Giorgio
fuente
Esto no cambia el tamaño del marco, desafortunadamente.
nickdnk
3

Con este método, también puede establecer el tamaño de fuente, el estilo de fuente y el fondo del encabezado . Hay 2 métodos para esto

Primer 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
fuente
1

Swift 2:

Como OP solicitó, solo ajuste el tamaño, no configurándolo como una fuente en negrita del sistema o lo que sea:

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
fuente
0

Esta es mi solución con swift 5.

Para controlar completamente la vista de la sección del encabezado, debe usar el método tableView (: viewForHeaderInsection: :) en su controlador, como lo mostró la publicación anterior. Sin embargo, hay un paso más: para mejorar el rendimiento, Apple recomienda no generar una nueva vista cada vez, sino reutilizar la vista de encabezado, al igual que reutilizar la celda de la tabla. Esto es por el método tableView.dequeueReusableHeaderFooterView (withIdentifier:). Pero el problema que tuve es que una vez que comience a usar esta función de reutilización, la fuente no funcionará como se esperaba. Otras cosas como el color, la alineación todo bien pero solo la fuente. Hay algunas discusiones, pero lo hice funcionar de la siguiente manera.

El problema es tableView.dequeueReusableHeaderFooterView (withIdentifier :) no es como tableView.dequeneReuseCell (:) que siempre devuelve una celda. El primero devolverá un cero si no hay nadie disponible. Incluso si devuelve una vista de encabezado de reutilización, no es su tipo de clase original, sino un UITableHeaderFooterView. Por lo tanto, debe juzgar y actuar de acuerdo con su propio código. Básicamente, si es nulo, obtenga una nueva vista de encabezado. Si no es nulo, fuerza a lanzar para que puedas 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
fuente