web-dev-qa-db-fra.com

UITableView titleForHeaderInSection affiche toutes les majuscules

J'utilise titleForHeaderInSection pour afficher un en-tête pour une section UITableView. Cela fonctionnait bien avec le SDK iOS6, mais le SDK iOS7 affiche l'en-tête dans tous les CAPS.

Je suppose que cela fait partie des directives d'interface humaine mises à jour d'Apple; tous les exemples y montrent des en-têtes en majuscules. En outre, tous les en-têtes de section dans les paramètres de mon iPhone sont en majuscules.

Cependant, je me demande s'il existe un moyen de contourner cela. Normalement, cela ne me dérangerait pas d'afficher des majuscules si cela améliore la cohérence, mais lorsque j'ai besoin d'afficher les noms des personnes dans un en-tête de section, c'est un peu gênant.

Quelqu'un sait-il comment se déplacer vers la capitalisation?

44
gbroekstg

Oui, nous avons eu un problème similaire à celui-ci, et ma propre solution était la suivante:

La documentation Apple UITableViewHeaderFooterView (le lien vers celle-ci est d'une longueur irritante mais vous pouvez la trouver facilement avec votre moteur de recherche préféré) indique que vous pouvez accéder au textLabel de la vue d'en-tête sans avoir à formater votre propre vue via la méthode viewForHeaderInSection.

textLabel Une étiquette de texte principale pour la vue. (lecture seulement)

@property (nonatomique, en lecture seule, conserver) UILabel * textLabel Discussion L'accès à la valeur de cette propriété fait que la vue crée une étiquette par défaut pour afficher une chaîne de texte détaillée. Si vous gérez vous-même le contenu de la vue en ajoutant des sous-vues à la propriété contentView, vous ne devez pas accéder à cette propriété.

L'étiquette est dimensionnée pour s'adapter au mieux à la zone d'affichage du contenu en fonction de la taille de la chaîne. Sa taille est également ajustée en fonction de la présence d'une étiquette de texte détaillée.

Avec quelques recherches supplémentaires, le meilleur endroit pour modifier le texte de l'étiquette était la méthode willDisplayHeaderView (suggérée dans Comment implémenter `viewForHeaderInSection` sur le style iOS7? ).

Donc, la solution que j'ai trouvée est assez simple et ne fait qu'une transformation de la chaîne d'étiquette de texte, après qu'elle ait été réellement définie par titleForHeaderInSection:

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
        //I have a static list of section titles in SECTION_ARRAY for reference.
        //Obviously your own section title code handles things differently to me.
    return [SECTION_ARRAY objectAtIndex:section];
}

puis appelez simplement la méthode willDisplayHeaderView pour modifier son apparence:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    if([view isKindOfClass:[UITableViewHeaderFooterView class]]){
        UITableViewHeaderFooterView *tableViewHeaderFooterView = (UITableViewHeaderFooterView *) view;
        tableViewHeaderFooterView.textLabel.text = [tableViewHeaderFooterView.textLabel.text capitalizedString];
    }
}

Vous pouvez y insérer vos propres clauses 'if' ou 'switch' car le numéro de section est également transmis à la méthode, donc j'espère que cela vous permettra d'afficher sélectivement votre nom d'utilisateur/client en mots majuscules.

Ben.

__

J'ai arrêté de mettre des scigs amusants dans SO 'car j'étais le seul à les trouver drôles.

69
Animal451

solution que j'ai trouvée est d'ajouter le titre dans la méthode "titleForHeaderInSection"

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
   return @"Table Title";
}

puis appelez la méthode willDisplayHeaderView pour mettre à jour:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section 
{
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
    header.textLabel.textColor = [UIColor darkGrayColor];
    header.textLabel.font = [UIFont boldSystemFontOfSize:18];
    CGRect headerFrame = header.frame;
    header.textLabel.frame = headerFrame;
    header.textLabel.text= @"Table Title";
    header.textLabel.textAlignment = NSTextAlignmentLeft;
}
21
user3540599

Si vous souhaitez simplement conserver la chaîne telle quelle, vous pouvez simplement le faire:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    if ([view isKindOfClass:[UITableViewHeaderFooterView class]] && [self respondsToSelector:@selector(tableView:titleForHeaderInSection:)]) {
        UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view;
        headerView.textLabel.text = [self tableView:tableView titleForHeaderInSection:section];
    }
}

Solution rapide:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let headerView = view as? UITableViewHeaderFooterView, self.respondsToSelector(Selector("tableView:titleForHeaderInSection:")) {
        headerView.textLabel?.text = self.tableView(tableView, titleForHeaderInSection: section)
    }
}
17
tobihagemann

Dans Swift,

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    let headerView = view as! UITableViewHeaderFooterView
    headerView.textLabel.text = "My_String"
}
15
Jeffrey Neo

Une solution que j'ai trouvée consiste à utiliser UITableViewHeaderFooterView.

Au lieu de

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return @"some title";
}

Faire

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *identifier = @"defaultHeader";
    UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier];
    if (!headerView) {
        headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:identifier];
    }
    headerView.textLabel.text = @"some title";
    return headerView;
}

L'inconvénient ennuyeux est que la vue de la table n'ajuste plus automatiquement la hauteur de l'en-tête de section pour vous. Donc, si la hauteur de votre en-tête varie, vous devrez faire quelque chose comme ceci:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    id headerAppearance = [UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil];
    UIFont *font = [headerAppearance font];
    CGFloat viewWidth = CGRectGetWidth(tableView.frame);
    CGFloat xInset = 10;
    CGFloat yInset = 5;
    CGFloat labelWidth = viewWidth - xInset * 2;
    CGSize size = [sectionInfo.name sizeWithFont:font constrainedToSize:CGSizeMake(labelWidth, MAXFLOAT)];
    return size.height + yInset * 2;
}

Je n'aime vraiment pas les informations de mise en page codées en dur (l'encart) de cette façon, car elles pourraient se casser dans la future version. Si quelqu'un a une meilleure solution pour obtenir/définir la hauteur de l'en-tête, je suis à l'écoute.

4
Joseph Lin

Merci @ Animal451. Il s'agit d'une solution plus générique qui fonctionnerait avec tout type de chaîne d'en-tête.

// We need to return the actual text so the header height gets correctly calculated
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return self.headerString;
}

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
    [header.textLabel setText:self.headerString];       //String in the header becomes uppercase. Workaround to avoid that.

}

Pour éviter la duplication, la chaîne d'en-tête peut être déclarée n'importe où ailleurs. Je l'ai fait dans la méthode -viewDidLoad.

3
moon4e

La solution la plus simple pour était ci-dessous: Swift 2.x

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

        header.textLabel?.text = header.textLabel?.text?.capitalizedString
}
3
Dheeraj D

En plus du message de @ Animal451. Pour Swift 3 vous pouvez utiliser

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
  guard section == 0 ,
    let tableViewHeaderFooterView = view as? UITableViewHeaderFooterView
    else { return }

  tableViewHeaderFooterView.textLabel?.text = "Your awesome string"
 }

Et puis ignorer - titleForHeaderInSection:

Gardez à l'esprit que ce code est destiné à la 1ère section uniquement. Si vous souhaitez parcourir toutes vos sections, vous devrez leur ajouter un support

3
KIO

Swift 3.x:

if let headerView = view as? UITableViewHeaderFooterView {
    headerView.textLabel?.text? = headerView.textLabel?.text?.capitalized ?? ""
}
2
Matt Bearson

Rapide

Dans la mise en œuvre, j'ai découvert que vous devez spécifier le texte d'en-tête de section dans les deux fonctions titleForHeaderInSection & willDisplayHeaderView, l'en-tête othervise se cache.

    extension ViewController: UITableViewDelegate, UITableViewDataSource {

        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
            let sectionHeader =  datasource[section].sectionHeader  

            // Header Title
            return sectionHeader 
        }

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

            guard let header = view as? UITableViewHeaderFooterView else { return }
            header.textLabel?.textColor = UIColor.darkGray
            header.textLabel?.font = UIFont.systemFont(ofSize: 20, weight: .semibold)
            header.textLabel?.frame = header.frame

            // Header Title
            header.textLabel?.text = datasource[section].sectionHeader
        }

    }
1
nikdange_me

La solution qui a fonctionné pour moi a été de créer un simple UILabelVariable d'instance à utiliser comme vue d'en-tête de section. (Vos besoins peuvent être différents, mais pour moi, je n'avais besoin que d'avoir du texte dans mon en-tête ...) Ensuite, à l'intérieur de viewForHeaderInSection, je configure l'étiquette comme requis, et je renvoie cette étiquette comme vue d'en-tête .

Ensuite, chaque fois que je veux mettre à jour le texte dans l'en-tête, je change simplement le texte de l'étiquette directement.

Dans le fichier .h:

@property (nonatomic, retain)  UILabel  *sectionHeaderLabel;

puis dans le fichier .m:

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return [self    refreshMySectionHeaderLabel]; // I created this handy little method to update the header text
}


// Get the latest text for the section header...
-(UILabel   *)  refreshMySectionHeaderLabel   {
    // Initialise the first time.    
    if( sectionHeaderLabel   ==  nil )   {
        sectionHeaderLabel   =   [[UILabel   alloc] initWithFrame:   CGRectNull];
    }

    // ...
    // May also set other attributes here (e.g. colour, font, etc...)
    // Figure out the text...    
    sectionHeaderLabel.text   =   @"Your updated text here...";


    return sectionHeaderLabel;
}

Lorsque je veux mettre à jour l'en-tête de ma section, j'appelle simplement:

[self refreshMySectionHeaderLabel];

... ou vous pouvez simplement appeler:

sectionHeaderLabel.text = @"The new text...";

Attention: je n'ai qu'une section (section 0). Vous devrez peut-être tenir compte de plusieurs sections ...

1
Bob Cowe

Une solution de revêtement, basée sur la réponse @Dheeraj D:

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
  (view as? UITableViewHeaderFooterView)?.textLabel?.text = (view as? UITableViewHeaderFooterView)?.textLabel?.text?.capitalized
}
1
Federico Zanetello

Avec RubyMotion/RedPotion, collez-le dans votre TableScreen:

  def tableView(_, willDisplayHeaderView: view, forSection: section)
    view.textLabel.text = self.tableView(_, titleForHeaderInSection: section)
  end

Je pense que ce qui se passe, c'est que quelque part là-dedans, le texte est réglé sur TOUTES MAJUSCULES. Cette petite astuce réinitialise le texte à ce qu'il était à l'origine. Fonctionne comme un charme pour moi!

0
Eli Duke