UINavigationBar titolo multilinea

Esiste un modo semplice per sovrascrivere il titleView dell’attuale elemento della barra di navigazione in una barra di navigazione all’interno di un controller di navigazione? Ho provato a creare un nuovo UIView e sostituire la proprietà titleView di topView con il mio UIVIew senza successo.

Fondamentalmente, voglio un titolo su più righe per il titolo della barra di navigazione. Eventuali suggerimenti?

Impostare la proprietà titleView di UINavigationItem . Ad esempio, nel metodo viewDidLoad del controller della viewDidLoad si potrebbe fare qualcosa del tipo:

 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 string"; self.navigationItem.titleView = label; #if !__has_feature(objc_arc) [label release]; #endif 

Si presenta così:

etichetta della barra del titolo multilinea

Ricorda che la proprietà titleView viene ignorata se leftBarButtonItem non è nil .

per 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 string" self.navigationItem.titleView = label 

per 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 

Soluzione rapida:

2 righe in NavigationBar :

 private func setupTitleView() { let topText = NSLocalizedString("key", comment: "") let bottomText = NSLocalizedString("key", comment: "") let titleParameters = [NSForegroundColorAttributeName : UIColor.(), NSFontAttributeName : UIFont.] let subtitleParameters = [NSForegroundColorAttributeName : UIColor.(), NSFontAttributeName : UIFont.] let title:NSMutableAttributedString = NSMutableAttributedString(string: topText, attributes: titleParameters) let subtitle:NSAttributedString = NSAttributedString(string: bottomText, attributes: subtitleParameters) title.appendAttributedString(NSAttributedString(string: "\n")) title.appendAttributedString(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.attributedText = title titleLabel.numberOfLines = 0 titleLabel.textAlignment = .Center navigationItem.titleView = titleLabel } 

2 righe in BarButton

  let string = NSLocalizedString("key", comment: "") let attributes = [NSForegroundColorAttributeName : UIColor., NSFontAttributeName : UIFont.] let size = (string as NSString).sizeWithAttributes(attributes) guard let height = navigationController?.navigationBar.frame.size.height else {return} let button:UIButton = UIButton(frame: CGRectMake(0, 0, size.width, height)) button.setAttributedTitle(NSAttributedString(string: string, attributes: attributes), 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 

risultato –

inserisci la descrizione dell'immagine qui

Dopo un sacco di modifiche, ancora non riuscivo a far funzionare la soluzione di petert per me su iOS 8. Ecco una soluzione copia-incollabile per iOS 8/9. Il merito va al post github di 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.attributedText = [[NSAttributedString alloc] initWithString:@"2\nLINES" attributes: self.navigationController.navigationBar.titleTextAttributes ]; [titleView sizeToFit]; // You'll need to set your frame otherwise if your line breaks aren't explcit. titleView; }); } } 

Cosa fare quando l’etichetta non è centrata

Se riscontri lo stesso problema di me – quell’etichetta non è centrata in navigationItem a causa del pulsante Indietro, incorpora la tua UILabel in UIView. UILabel non è quindi costretto a crescere con il suo testo, ma smette di crescere quando aumenta la larghezza della vista. Ulteriori informazioni su questo problema che puoi trovare qui: Imansible impostare titleView al centro della barra di navigazione perché pulsante indietro (risposta di Darren)

Non centrato:

inserisci la descrizione dell'immagine qui

 - (void)setTwoLineTitle:(NSString *)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; } 

centrato:

inserisci la descrizione dell'immagine qui

 - (void)setTwoLineTitle:(NSString *)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; } 

Ecco una versione di Swift 3 per gestire un titolo multilinea:

 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 } 

Ecco un modo Swift 4 per farlo-

 let upperTitle = NSMutableAttributedString(string: "\(text1)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProDisplay-Heavy", size: 17)!]) let lowerTitle = NSMutableAttributedString(string: "\n\((text2)!)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProText-Light", size: 11)! , NSAttributedStringKey.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.attributedText = upperTitle //assign it to attributedText instead of text self.navigationItem.titleView = label1 

La maggior parte delle soluzioni, eccetto quella di @gbk, utilizza l’altezza hardcoded di 44pt per UIView (vista wrapper) e UILabel. Tutti sono creati da codici. Ho trascurato la soluzione di @gbk che leggeva in modo dinamico l’altezza della barra di navigazione.

Ho riscontrato un problema con orientation = landscape su iOS 11 (iPhone 5s). L’altezza dell’etichetta non verrà regolata e quando imposto una riga di testo per il paesaggio, il testo si allinea alla parte inferiore della barra di navigazione.

In qualche modo ho scoperto che posso aggiungere UILabel nello Storyboard e creare un IBOutlet per questo. Non è più bello?

  1. Aggiungi un UIView alla barra di navigazione nello storyboard. Quando lo trascini sulla barra di navigazione, apparirà come una scatola blu. Se viene visualizzato un tratto verticale, lo si aggiunge all’array di elementi del pulsante della barra sinistra / destra. Nota: non può esserci UN ONE UIView. Se lo aggiungi correttamente, apparirà sotto Navigation Item nel pannello delle scene (a sinistra).
  2. Trascina un UILabel in questo UIView. inserisci la descrizione dell'immagine qui
  3. Poiché UIView non avrà SIZE ma centralizzato nella barra di navigazione, non è ansible aggiungere il vincolo di quattro zero. Basta aggiungere due vincoli a UILabel in modo che si posizionino nel centro di superview: Allinea al centro X e Y a Superview.
  4. Configura UILabel come al solito. Per linee multiple, ho impostato il numero di linee su zero (0).
  5. Crea un IBOutlet sul tuo controller di visualizzazione e puoi usarlo come al solito. Per avere diverse dimensioni del testo, usa la stringa di attributi (molte soluzioni sopra).

Ho provato su iPhone 5s con iOS 11.2.6 e il testo era appena posizionato al centro senza problemi, funziona bene su ritratto e paesaggio.

Swift 4

 extension UINavigationItem { @objc func setTwoLineTitle(lineOne: String, lineTwo: String) { let titleParameters = [NSAttributedStringKey.foregroundColor : UIColor.white, NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 17)] as [NSAttributedStringKey : Any] let subtitleParameters = [NSAttributedStringKey.foregroundColor : UIColor.flatWhite(), NSAttributedStringKey.font : UIFont.systemFont(ofSize: 12)] as [NSAttributedStringKey : Any] let title:NSMutableAttributedString = NSMutableAttributedString(string: lineOne, attributes: titleParameters) let subtitle:NSAttributedString = NSAttributedString(string: lineTwo, attributes: subtitleParameters) title.append(NSAttributedString(string: "\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.attributedText = title titleLabel.numberOfLines = 0 titleLabel.textAlignment = .center titleView = titleLabel } } 

Font, colore e altezza della barra di navigazione sono codificati qui.