Pergunta

Existe uma maneira direta de substituir o titleView do item atual da barra de navegação em uma barra de navegação dentro de um controlador de navegação?Tentei criar um novo UIView e substituir a propriedade titleView de topView pelo meu próprio UIVIew, sem sucesso.

Basicamente, quero um título com várias linhas para o título da barra de navegação.Alguma sugestão?

Foi útil?

Solução

Colocou o titleView propriedade do UINavigationItem. Por exemplo, no View Controller's viewDidLoad Método você poderia fazer algo como:

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

Aparece assim:

multi-line titlebar label

Lembre o titleView propriedade é ignorado E se leftBarButtonItem não é nil.

Outras dicas

Para 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

Para 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   

Solução rápida:

2 linhas em NavigationBar:

private func setupTitleView() {
    let topText = NSLocalizedString("key", comment: "")
    let bottomText = NSLocalizedString("key", comment: "")

    let titleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
                           NSFontAttributeName : UIFont.<Font>]
    let subtitleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
                              NSFontAttributeName : UIFont.<Font>]

    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 linha em BarButton

    let string = NSLocalizedString("key", comment: "")
    let attributes = [NSForegroundColorAttributeName : UIColor.<Color>,
                      NSFontAttributeName : UIFont.<Font>]
    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(<SELECTOR>), forControlEvents: .TouchUpInside)
    button.titleLabel?.numberOfLines = 0
    button.titleLabel?.textAlignment = .Right
    let rightBarButton = UIBarButtonItem(customView: button)
    navigationItem.rightBarButtonItem = rightBarButton

resultado -

enter image description here

Depois de muitos ajustes, eu ainda não conseguia fazer a solução de Petert funcionar para mim no iOS 8. Aqui está uma solução de cópia de cola para iOS 8/9. Crédito vai para Post 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.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;
        });
    }
}

O que fazer quando o rótulo não está centrado

Se você encontrar o mesmo problema que eu - esse rótulo não está centrado no NavigationItem por causa do botão traseiro, incorpore seu uilabel ao UIView. O Uilabel não é forçado a crescer com o texto, mas pare de crescer quando a largura da largura é a largura da visão. Mais sobre esse problema que você pode encontrar aqui: Não é possível definir o TitleView no centro da barra de navegação porque o botão traseiro (Resposta de Darren)

Não está centrado:

enter image description here

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

Centrado:

enter image description here

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

Aqui está um Swift 3 Versão para lidar com um título de multilina:

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
}

Aqui está um Swift 4 maneira de fazer isso-

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

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

A altura da barra de fonte, cor e navegação é codificada aqui.

A maioria das soluções, exceto a de @gbk, usa altura 44pt codificada para UIView (visualização do wrapper) e UILabel.Todos são criados por códigos.Ignorei a solução @gbk que lê dinamicamente a altura da barra de navegação.

Eu tive problemas quando orientation = landscape no iOS 11 (iPhone 5s).A altura do rótulo não será ajustada e quando eu definir uma linha de texto para paisagem, o texto será alinhado à parte inferior da barra de navegação.

De alguma forma, descobri que posso adicionar o UILabel no Storyboard e criar um IBOutlet para isso.Não é mais legal?

  1. Adicione um UIView à barra de navegação no storyboard.Ao arrastá-lo sobre a barra de navegação, ele aparecerá como uma caixa azul.Se um traço vertical aparecer, você o está adicionando à matriz de itens dos botões da barra esquerda/direita.Observação:só pode haver UM UIView.Se você adicioná-lo corretamente, ele aparecerá em Navigation Item no painel de cena (à esquerda).
  2. Arraste um UILabel para este UIView. enter image description here
  3. Como o UIView terá SEM TAMANHO mas centralizado na barra de navegação, você não pode adicionar restrições de quatro zeros.Basta adicionar duas restrições ao UILabel para que ele fique no centro da supervisão:Alinhe o centro X e Y para Superview.
  4. Configure o UILabel normalmente.Para linhas múltiplas, defino o número de linhas como zero (0).
  5. Criar um IBOutlet no seu controlador de visualização e você pode usá-lo normalmente.Para ter tamanhos de texto diferentes, use string de atributos (muitas soluções acima).

Testei no iPhone 5s com iOS 11.2.6 e o ​​texto apenas posicionou no centro sem problemas, funcionou bem em retrato e paisagem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top