Modification de la taille de la police pour les en-têtes de section UITableView

139

Quelqu'un peut-il s'il vous plaît me renseigner sur la manière la plus simple de modifier la taille de police du texte dans un en-tête de section UITableView?

J'ai les titres de section implémentés en utilisant la méthode suivante:

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

Ensuite, je comprends comment modifier avec succès la hauteur de l'en-tête de section à l'aide de cette méthode:

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

J'ai les cellules UITableView remplies à l'aide de cette méthode:

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

Cependant, je ne sais pas comment augmenter la taille de la police - ou d'ailleurs le style de police - du texte de l'en-tête de section?

Quelqu'un peut-il s'il vous plaît aider? Merci.

JRD8
la source
1
Version Swift
Juan Boero

Réponses:

118

Malheureusement, vous devrez peut-être ignorer ceci:

En Objective-C:

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

Dans Swift:

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

Essayez quelque chose comme ceci:

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

Dans 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
la source
1
Je vous remercie. Cela a parfaitement fonctionné. Très appréciée.
JRD8
5
Bien que ce soit une solution correcte, soyez prudent avec cette méthode. Pour un en-tête de plus d'une ligne, vous devrez effectuer les calculs de la hauteur de l'en-tête dans tableView:heightForHeaderInSection:lesquels peuvent être encombrants.
Leo Natan
3
J'ai essayé cela et bien que cela fonctionne si vous faites défiler le tableau vers le haut, l'étiquette d'en-tête reste à l'écran et superpose les cellules. :(
Plasma
2
@trss Je pense que vous trouverez que ce n'est pas un comportement attendu. Je ne parle pas de la section d'en-tête qui reste là, seulement de l'étiquette, et de sa superposition aux cellules lorsqu'elles passent en dessous, ce qui donne un vrai désordre. J'ai trouvé un meilleur moyen d'y parvenir et je le posterai une fois que je le retrouverai.
Plasma
1
@ mosca1337 il n'est pas nécessaire de créer une autre vue, vous pouvez afficher le véritable 'UITableViewHeaderFooterView' et ajuster les paramètres.
Juan Boero
368

Une autre façon de procéder serait de répondre à la UITableViewDelegateméthode willDisplayHeaderView. La vue transmise est en fait une instance d'un fichier UITableViewHeaderFooterView.

L'exemple ci-dessous modifie la police et centre également le texte du titre verticalement et horizontalement dans la cellule. Notez que vous devez également répondre à heightForHeaderInSectionpour que toute modification de la hauteur de votre en-tête soit prise en compte dans la disposition de la vue tableau. (Autrement dit, si vous décidez de modifier la hauteur de l'en-tête dans cette willDisplayHeaderViewméthode.)

Vous pouvez alors répondre à la titleForHeaderInSectionméthode pour réutiliser cet en-tête configuré avec différents titres de section.

Objectif 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

(Remarque: si votre contrôleur de vue est un descendant de a UITableViewController, cela devra être déclaré comme 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

Ce code garantit également que l'application ne plante pas si votre vue d'en-tête est autre chose qu'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
la source
3
Cette méthode a fonctionné beaucoup mieux pour moi que celle ci
Plasma
6
Meilleure réponse que j'ai vue.
phatmann
2
Ce serait la manière «appropriée» d'ajuster les informations, en supposant qu'il n'y a pas d'autre raison de sous-classer (comme l'ajout de vues, par exemple). En outre, cette méthode peut être utilisée pour mettre à jour le texte d'en-tête pour Dynamic Type. Utilisez simplement: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];et / ou header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];avec les autres étapes nécessaires (voir ici: captechconsulting.com/blog/john-szumski/… )
leanne
3
Cela ne redimensionne pas la vue d'en-tête, donc si votre police est plus grande ou significativement différente, comme Zapfino (ne demandez pas pourquoi), cela coupera le texte. Si vous devez calculer vous-même la taille, c'est un gâchis et vous ne devriez pas le faire.
Leo Natan
@CocoaPriest Ne plante pas dans ma version beta, tho. (Semences GM 2)
Patrick Bassut
96

Bien que la réponse de mosca1337 soit une solution correcte, soyez prudent avec cette méthode. Pour un en-tête avec du texte de plus d'une ligne, vous devrez effectuer les calculs de la hauteur de l'en-tête dans tableView:heightForHeaderInSection:lesquels peuvent être encombrants.

Une méthode très préférée consiste à utiliser l'API d'apparence:

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

Cela changera la police, tout en laissant la table pour gérer les hauteurs elle-même.

Pour des résultats optimaux, sous-classez la vue de table et ajoutez-la à la chaîne de confinement (in appearanceWhenContainedIn:) pour vous assurer que la police n'est modifiée que pour les vues de table spécifiques.

Leo Natan
la source
1
En cas de sous-classement, vous retourneriez de toute façon une vue personnalisée à partir de la - tableView:viewForHeaderInSection:droite? Dans ce cas, la police peut être définie ici. C'est de toute façon ce que fait la solution de @ mosca1337.
trss
1
Haha, eh bien je suis un woozey après hier. Sous-classez la vue de table et ajoutez-la à la liste de conteneurs. ;-)
Leo Natan
2
Cette solution provoque de nombreux bugs avec le calcul de la taille réelle du pied de page / de l'en-tête. Je peux montrer quelques exemples lorsque les titres sont coupés pendant que la police personnalisée est configurée.
kas-kad
5
Swift 3 :UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
Eric Hodgins
3
Cela ne redimensionne pas correctement l'étiquette pour s'adapter à la police sur iOS 11. De plus, le défilement vers le haut et vers le bas après le chargement des vues les réinitialise à la police par défaut.
nickdnk
25

Pour iOS 7, j'utilise ceci,


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

Voici la version Swift 3.0 avec redimensionnement de l'en-tête

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
la source
6
Cela ne dimensionnera pas la vue d'en-tête pour l'adapter à la nouvelle police.
Leo Natan
@LeoNatan Comment pouvons-nous dimensionner la vue d'en-tête pour l'adapter à la nouvelle police - cela peut-il être fait avec cette méthode?
SAHM
Je voulais préciser que j'ai bien vu votre réponse ci-dessus, mais je veux uniquement changer la police pour limiter la taille lorsqu'une police sélectionnée par l'utilisateur (accessibilité) dépasse une certaine taille (donc, pas tout le temps). Je crois que je dois vérifier et éventuellement modifier la police dans willDisplayHeaderView, alors y a-t-il un moyen de recalculer la hauteur de la vue si la police est modifiée?
SAHM
19

Swift 3:

Le moyen le plus simple d'ajuster uniquement la taille:

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
la source
C'est la manière la plus simple que je recherche.
Ryan
Fonctionne dans Swift 4! N'oubliez pas "override func .."
Matvey
8

Swift 2.0 :

  1. Remplacez l'en-tête de section par défaut par un UILabel entièrement personnalisable.

Implémentez viewForHeaderInSection, comme ceci:

  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. Modifiez l'en-tête par défaut (conserve la valeur par défaut).

Implémentez willDisplayHeaderView, comme ceci:

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

N'oubliez pas: si vous utilisez des cellules statiques, le premier en-tête de section est rempli plus haut que les autres en-têtes de section en raison du haut de UITableView; pour résoudre ce problème:

Implémentez heightForHeaderInSection, comme ceci:

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

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

La réponse de la version Swift 4 de Leo Natan est

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

Si vous souhaitez définir une police personnalisée, vous pouvez utiliser

if let font = UIFont(name: "font-name", size: 12) {
    UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = font
}
Giorgio
la source
Cela ne redimensionne malheureusement pas le cadre.
nickdnk
3

Avec cette méthode, vous pouvez également définir la taille de la police, le style de police et l'arrière-plan de l'en-tête . il existe 2 méthodes pour cela

Première méthode

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

Deuxième méthode

- (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
la source
1

Swift 2:

Comme OP l'a demandé, ajustez uniquement la taille, ne la définissez pas comme une police système en gras ou autre:

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
la source
0

C'est ma solution avec Swift 5.

Pour contrôler entièrement la vue en coupe de l'en-tête, vous devez utiliser la méthode tableView (: viewForHeaderInsection: :) dans votre contrôleur, comme l'a montré l'article précédent. Cependant, il y a une étape supplémentaire: pour améliorer les performances, Apple recommande de ne pas générer une nouvelle vue à chaque fois mais de réutiliser la vue d'en-tête, tout comme réutiliser la cellule du tableau. C'est par la méthode tableView.dequeueReusableHeaderFooterView (withIdentifier:). Mais le problème que j'ai eu est qu'une fois que vous commencez à utiliser cette fonction de réutilisation, la police ne fonctionnera pas comme prévu. D'autres choses comme la couleur, l'alignement sont très bien mais juste la police. Il y a quelques discussions mais je l'ai fait fonctionner comme suit.

Le problème est que tableView.dequeueReusableHeaderFooterView (withIdentifier :) n'est pas comme tableView.dequeneReuseCell (:) qui renvoie toujours une cellule. Le premier retournera un zéro si personne n'est disponible. Même s'il renvoie une vue d'en-tête de réutilisation, il ne s'agit pas de votre type de classe d'origine, mais d'un UITableHeaderFooterView. Vous devez donc faire le jugement et agir selon votre propre code. En gros, s'il est nul, obtenez une toute nouvelle vue d'en-tête. Sinon, forcez à lancer pour que vous puissiez contrôler.

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
la source