Titre multi-ligne UINavigationBar

Existe-t-il un moyen simple de remplacer le titreAffichage de l’élément de la barre de navigation actuelle dans une barre de navigation d’un contrôleur de navigation? J’ai essayé de créer un nouvel UIView et de remplacer la propriété titleView de topView par mon propre UIVIew sans succès.

En gros, je veux un titre multi-ligne pour le titre de la barre de navigation. Aucune suggestion?

    Définissez la propriété titleView du UINavigationItem . Par exemple, dans la méthode viewDidLoad du contrôleur de viewDidLoad , vous pouvez faire quelque chose comme:

     UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 480, 44)]; label.backgroundColor = [UIColor clearColor]; label.numberOfLines = 2; label.font = [UIFont boldSystemFontOfSize: 14.0f]; label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5]; label.textAlignment = UITextAlignmentCenter; label.textColor = [UIColor whiteColor]; label.text = @"This is a\nmultiline ssortingng"; self.navigationItem.titleView = label; #if !__has_feature(objc_arc) [label release]; #endif 

    Il apparaît comme ceci:

    étiquette de barre de titre multi-ligne

    N’oubliez pas que la propriété titleView est ignorée si leftBarButtonItem n’est pas nil .

    pour Swift:

     let label = UILabel(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, 44)) label.backgroundColor = UIColor.clearColor() label.numberOfLines = 0 label.textAlignment = NSTextAlignment.Center label.text = "multiline ssortingng" self.navigationItem.titleView = label 

    pour swift 4:

      let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0)) label.backgroundColor = UIColor.clear label.numberOfLines = 0 label.textAlignment = NSTextAlignment.center label.text = "first line\nsecond line" self.navigationItem.titleView = label 

    Solution rapide:

    2 lignes dans NavigationBar :

     private func setupTitleView() { let topText = NSLocalizedSsortingng("key", comment: "") let bottomText = NSLocalizedSsortingng("key", comment: "") let titleParameters = [NSForegroundColorAtsortingbuteName : UIColor.(), NSFontAtsortingbuteName : UIFont.] let subtitleParameters = [NSForegroundColorAtsortingbuteName : UIColor.(), NSFontAtsortingbuteName : UIFont.] let title:NSMutableAtsortingbutedSsortingng = NSMutableAtsortingbutedSsortingng(ssortingng: topText, atsortingbutes: titleParameters) let subtitle:NSAtsortingbutedSsortingng = NSAtsortingbutedSsortingng(ssortingng: bottomText, atsortingbutes: subtitleParameters) title.appendAtsortingbutedSsortingng(NSAtsortingbutedSsortingng(ssortingng: "\n")) title.appendAtsortingbutedSsortingng(subtitle) let size = title.size() let width = size.width guard let height = navigationController?.navigationBar.frame.size.height else {return} let titleLabel = UILabel(frame: CGRectMake(0,0, width, height)) titleLabel.atsortingbutedText = title titleLabel.numberOfLines = 0 titleLabel.textAlignment = .Center navigationItem.titleView = titleLabel } 

    2 lignes dans BarButton

      let ssortingng = NSLocalizedSsortingng("key", comment: "") let atsortingbutes = [NSForegroundColorAtsortingbuteName : UIColor., NSFontAtsortingbuteName : UIFont.] let size = (ssortingng as NSSsortingng).sizeWithAtsortingbutes(atsortingbutes) guard let height = navigationController?.navigationBar.frame.size.height else {return} let button:UIButton = UIButton(frame: CGRectMake(0, 0, size.width, height)) button.setAtsortingbutedTitle(NSAtsortingbutedSsortingng(ssortingng: ssortingng, atsortingbutes: atsortingbutes), forState: .Normal) button.addTarget(self, action: #selector(), forControlEvents: .TouchUpInside) button.titleLabel?.numberOfLines = 0 button.titleLabel?.textAlignment = .Right let rightBarButton = UIBarButtonItem(customView: button) navigationItem.rightBarButtonItem = rightBarButton 

    résultat –

    entrer la description de l'image ici

    Après de nombreuses modifications, je ne pouvais toujours pas utiliser la solution de petert sur iOS 8. Voici une solution de copier-coller pour iOS 8/9. Le crédit va à la poste de github de Matt Curtis

     - (void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if(!self.navigationItem.titleView){ self.navigationItem.titleView = ({ UILabel *titleView = [UILabel new]; titleView.numberOfLines = 0; titleView.textAlignment = NSTextAlignmentCenter; titleView.atsortingbutedText = [[NSAtsortingbutedSsortingng alloc] initWithSsortingng:@"2\nLINES" atsortingbutes: self.navigationController.navigationBar.titleTextAtsortingbutes ]; [titleView sizeToFit]; // You'll need to set your frame otherwise if your line breaks aren't explcit. titleView; }); } } 

    Que faire lorsque l’étiquette n’est pas centrée

    Si vous rencontrez le même problème que moi – cette étiquette n’est pas centrée dans navigationItem à cause du bouton Retour, incorporez votre UILabel à UIView. UILabel n’est alors pas obligé de croître avec son texte, mais cesse de croître quand sa largeur augmente la largeur de la vue. Vous trouverez plus d’informations sur ce problème ici: Impossible de définir titleView au centre de la barre de navigation car le bouton retour (la réponse de Darren)

    Non centré:

    entrer la description de l'image ici

     - (void)setTwoLineTitle:(NSSsortingng *)titleText color:(UIColor *)color font:(UIFont *)font { CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)]; label.backgroundColor = [UIColor clearColor]; label.numberOfLines = 2; label.font = font; label.adjustsFontSizeToFitWidth = YES; label.textAlignment = UITextAlignmentCenter; label.textColor = color; label.text = titleText; self.navigationItem.titleView = label; } 

    Centré:

    entrer la description de l'image ici

     - (void)setTwoLineTitle:(NSSsortingng *)titleText color:(UIColor *)color font:(UIFont *)font { CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2; UIView *wrapperView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)]; label.backgroundColor = [UIColor clearColor]; label.numberOfLines = 2; label.font = font; label.adjustsFontSizeToFitWidth = YES; label.textAlignment = UITextAlignmentCenter; label.textColor = color; label.text = titleText; [wrapperView addSubview:label]; self.navigationItem.titleView = wrapperView; } 

    Voici une version de Swift 3 pour gérer un titre multiligne:

     override func viewDidLoad() { super.viewDidLoad() let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)) label.backgroundColor = .clear label.numberOfLines = 0 label.textAlignment = .center label.font = UIFont.boldSystemFont(ofSize: 14.0) label.text = "This is a Multi-Line title of UINavigationBar" self.navigationItem.titleView = label } 

    Voici un moyen rapide de le faire –

     let upperTitle = NSMutableAtsortingbutedSsortingng(ssortingng: "\(text1)", atsortingbutes: [NSAtsortingbutedSsortingngKey.font: UIFont(name: "SFProDisplay-Heavy", size: 17)!]) let lowerTitle = NSMutableAtsortingbutedSsortingng(ssortingng: "\n\((text2)!)", atsortingbutes: [NSAtsortingbutedSsortingngKey.font: UIFont(name: "SFProText-Light", size: 11)! , NSAtsortingbutedSsortingngKey.foregroundColor: UIColor(hex: "#607D8B")]) upperTitle.append(lowerTitle) let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height:44)) label1.numberOfLines = 0 label1.textAlignment = .center label1.atsortingbutedText = upperTitle //assign it to atsortingbutedText instead of text self.navigationItem.titleView = label1 

    La plupart des solutions, à l’exception de celle de @gbk, utilisent la hauteur codée en dur 44pt pour UIView (vue wrapper) et UILabel. Tous sont créés par des codes. J’ai négligé la solution @gbk qui lit dynamicment la hauteur de la barre de navigation.

    J’ai rencontré un problème lorsque l’ orientation = landscape sur iOS 11 (iPhone 5s). La hauteur de l’étiquette ne s’ajustera pas et lorsque je définirai une ligne de texte pour le paysage, le texte sera aligné au bas de la barre de navigation.

    D’une manière ou d’une autre, j’ai trouvé que je pouvais append UILabel dans Storyboard et créer un IBOutlet pour cela. N’est-ce pas mieux?

    1. Ajouter un UIView à la barre de navigation dans le storyboard. Lorsque vous le faites glisser sur la barre de navigation, il apparaîtra comme une boîte bleue. Si un trait vertical apparaît, vous l’ajoutez au tableau des éléments du bouton de la barre gauche / droite. Note: il ne peut y avoir qu’une seule UIView. Si vous l’ajoutez correctement, il apparaîtra sous Navigation Item sur le panneau de scène (à gauche).
    2. Faites glisser un UILabel dans cet UIView. entrer la description de l'image ici
    3. Comme UIView n’aura AUCUNE TAILLE mais centralisé dans la barre de navigation, vous ne pouvez pas append une contrainte de quatre zéro. Ajoutez simplement deux contraintes à l’UILabel afin qu’il se positionne au centre de la superview: Alignez le centre X et Y sur Superview.
    4. Configurez UILabel comme d’habitude. Pour les lignes multiples, je mets le nombre de lignes à zéro (0).
    5. Créez un IBOutlet sur votre contrôleur de vue et vous pourrez l’utiliser comme d’habitude. Pour avoir une taille de texte différente, utilisez la chaîne d’atsortingbut (beaucoup de solutions ci-dessus).

    J’ai testé sur iPhone 5s avec iOS 11.2.6 et le texte juste positionné au centre sans problème, fonctionne bien sur le portrait et le paysage.

    Swift 4

     extension UINavigationItem { @objc func setTwoLineTitle(lineOne: Ssortingng, lineTwo: Ssortingng) { let titleParameters = [NSAtsortingbutedSsortingngKey.foregroundColor : UIColor.white, NSAtsortingbutedSsortingngKey.font : UIFont.boldSystemFont(ofSize: 17)] as [NSAtsortingbutedSsortingngKey : Any] let subtitleParameters = [NSAtsortingbutedSsortingngKey.foregroundColor : UIColor.flatWhite(), NSAtsortingbutedSsortingngKey.font : UIFont.systemFont(ofSize: 12)] as [NSAtsortingbutedSsortingngKey : Any] let title:NSMutableAtsortingbutedSsortingng = NSMutableAtsortingbutedSsortingng(ssortingng: lineOne, atsortingbutes: titleParameters) let subtitle:NSAtsortingbutedSsortingng = NSAtsortingbutedSsortingng(ssortingng: lineTwo, atsortingbutes: subtitleParameters) title.append(NSAtsortingbutedSsortingng(ssortingng: "\n")) title.append(subtitle) let size = title.size() let width = size.width let height = CGFloat(44) let titleLabel = UILabel(frame: CGRect.init(x: 0, y: 0, width: width, height: height)) titleLabel.atsortingbutedText = title titleLabel.numberOfLines = 0 titleLabel.textAlignment = .center titleView = titleLabel } } 

    La police, la couleur et la hauteur de la barre de navigation sont codées en dur ici.