47 votes

Ajouter un sous-titre sous le titre dans le contrôleur de barre de navigation dans Xcode

Donc, je veux ajouter un "sous-titre" sous le titre dans la barre de navigation dans le contrôleur de navigation.

Presque tout ce que j'ai trouvé jusqu'à présent veut que j'utilise CGRect. Je ne sais pas trop ce que c'est et on dirait que cela veut que je crée une toute nouvelle vue, ce n'est pas ce que je veux faire.

Ma question est, est-ce qu'il y a une méthode simple pour ajouter une vue de sous-titre?

La chose la plus proche que j'ai trouvée a été postée sur stack overflow et voici le lien :

Créer un sous-titre dans la barre de navigation

Apparemment, l'année dernière cela fonctionnait mais maintenant j'obtiens des erreurs et c'est dans mon viewDidLoad...

J'ai essayé ceci :

self.navigationController?.navigationItem.prompt = "Sous-titre ici"

C'est la seule chose qui ne montre aucune erreur mais qui ne fonctionne toujours pas. Il ne fait littéralement rien. Du moins, rien n'est visible au moment de l'exécution.

Accessoirement, Swift est préféré. Merci!

0 votes

Avez-vous essayé self.navigationItem.prompt = "Sous-titre" ?

1 votes

@tktsubota Cela placera le sous-titre au-dessus du titre et non en dessous du titre

0 votes

@RajanMaheshwari Oui, j'ai fait un test et j'ai découvert ça.

74voto

user2325031 Points 61

Voici ma version utilisant une vue en pile sur une extension.

extension UINavigationItem {
    func setTitle(title:String, subtitle:String) {

        let one = UILabel()
        one.text = title
        one.font = UIFont.systemFont(ofSize: 17)
        one.sizeToFit()

        let two = UILabel()
        two.text = subtitle
        two.font = UIFont.systemFont(ofSize: 12)
        two.textAlignment = .center
        two.sizeToFit()

        let stackView = UIStackView(arrangedSubviews: [one, two])
        stackView.distribution = .equalCentering
        stackView.axis = .vertical
        stackView.alignment = .center

        let width = max(one.frame.size.width, two.frame.size.width)
        stackView.frame = CGRect(x: 0, y: 0, width: width, height: 35)

        one.sizeToFit()
        two.sizeToFit()

        self.titleView = stackView
    }
}

3 votes

Titre et sous-titre glissent vers le centre de la gauche lorsqu'on pousse depuis le contrôleur de navigation des solutions de contournement

11 votes

Pour moi, c'est la réponse la plus propre, elle n'a pas de nombres magiques comme la première réponse. Je vais simplement ajouter stackView.alignment = .center après avoir défini l'axe, sinon il n'apparaîtra pas totalement centré si le sous-titre est plus grand. De plus, je supprimerais les deux derniers appels à sizeToFit(), puisque vous les avez appelés sur les étiquettes.

0 votes

La balise title par défaut a-t-elle également une valeur constante de police de 17 ?

60voto

Rajan Maheshwari Points 9586

Bien qu'il existe une solution, elle présente des problèmes connus

La solution consiste à écrire une fonction comme celle-ci

func setTitle(title:String, subtitle:String) -> UIView {
    let titleLabel = UILabel(frame: CGRectMake(0, -2, 0, 0))

    titleLabel.backgroundColor = UIColor.clearColor()
    titleLabel.textColor = UIColor.grayColor()
    titleLabel.font = UIFont.boldSystemFontOfSize(17)
    titleLabel.text = title
    titleLabel.sizeToFit()

    let subtitleLabel = UILabel(frame: CGRectMake(0, 18, 0, 0))
    subtitleLabel.backgroundColor = UIColor.clearColor()
    subtitleLabel.textColor = UIColor.blackColor()
    subtitleLabel.font = UIFont.systemFontOfSize(12)
    subtitleLabel.text = subtitle
    subtitleLabel.sizeToFit()

    let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
    titleView.addSubview(titleLabel)
    titleView.addSubview(subtitleLabel)

    let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width

    if widthDiff < 0 {
        let newX = widthDiff / 2
        subtitleLabel.frame.origin.x = abs(newX)
    } else {
        let newX = widthDiff / 2
        titleLabel.frame.origin.x = newX
    }

    return titleView
}

Utilisez cette fonction pour personnaliser la vue du titre de la navigation dans viewDidLoad

self.navigationItem.titleView = setTitle("Titre", subtitle: "Sous-titre")

Le seul problème connu est que si le sous-titre devient très grand, un décalage se produit.

Résultat final entrer la description de l'image ici

Source: https://gist.github.com/nazywamsiepawel/0166e8a71d74e96c7898

1 votes

C'est beaucoup plus de code que je ne m'y attendais mais ça fonctionne. J'espère vraiment qu'Apple ajoutera un moyen plus simple. Le sous-titre ne semble pas être quelque chose de si farfelu... lol

0 votes

Merci beaucoup au fait! :) @rajan

0 votes

J'ai besoin de quelque chose comme ceci, si le titre est vide alors le titre doit être au centre. Je dois implémenter dans l'application de chat. Si l'utilisateur commence à taper, alors le sous-titre s'affiche. Pour en savoir plus, voir WhatsApp.

11voto

AdrianGutierrez Points 276

Merci beaucoup pour ta réponse! @RajanMaheshwari

Ton code a parfaitement fonctionné sauf l'instruction if que tu as faite avec le widthDiff..

Je l'ai ajustée un peu et tout fonctionne parfaitement.

if widthDiff < 0 {
        let newX = widthDiff / 2
        subtitleLabel.frame.origin.x = abs(newX)
    } else {
        let newX = widthDiff / 2
        titleLabel.frame.origin.x = newX
    }

Merci encore pour ta réponse!

0 votes

Super correction! J'ai dû le faire aussi.

4voto

Mubeen Qazi Points 99

Si quelqu'un recherche le code Objective-C de la solution mentionnée ci-dessus :

   UILabel *title = [[UILabel alloc]init];
   UILabel *subtitle = [[UILabel alloc]init];

   [title setFont:[UIFont systemFontOfSize:12]];
   [title setTextColor:[UIColor whiteColor]];
   [title setFont:[UIFont systemFontOfSize:17]];
   [title sizeToFit];
   title.text = @"Titre";

   [subtitle setTextColor:[UIColor whiteColor]];
   [subtitle setFont:[UIFont systemFontOfSize:12]];
   [subtitle setTextAlignment:NSTextAlignmentCenter];
   [subtitle sizeToFit];
   subtitle.text = @"Sous-titre";

   UIStackView *stackVw = [[UIStackView alloc]initWithArrangedSubviews:@[title,subtitle]];
   stackVw.distribution = UIStackViewDistributionEqualCentering;
   stackVw.axis = UILayoutConstraintAxisVertical;
   stackVw.alignment =UIStackViewAlignmentCenter;

   [stackVw setFrame:CGRectMake(0, 0, MAX(title.frame.size.width, subtitle.frame.size.width), 35)];
   self.navigationItem.titleView = stackVw;

2voto

Nick Kirsten Points 583

Merci pour la réponse @RajanMaheshwari

Si quelqu'un rencontre le problème où le titre devient désaligné lorsque le texte du sous-titre est plus long que celui du titre, j'ai ajouté le code suivant à la réponse de Rajan ci-dessus, juste en dessous de l'instantiation du subtitleLabel :

// Fix incorrect width bug
if (subtitleLabel.frame.size.width > titleLabel.frame.size.width) {
    var titleFrame = titleLabel.frame
    titleFrame.size.width = subtitleLabel.frame.size.width
    titleLabel.frame = titleFrame
    titleLabel.textAlignment = .center
}

J'espère que cela aidera quelqu'un qui a rencontré le même problème que moi

0 votes

Comme indiqué dans le commentaire de @GerardoMR ci-dessus - vous pouvez centrer le titre/sous-titre en utilisant le paramètre UIStackView : stackView.alignment = .center

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X