2012-03-29 22 views
16

Tengo un título de UINavigationBar personalizado y un botón de retroceso personalizado. Mi problema es que el título no está centrado en el iPhone. Es como si mi botón de retroceso estuviera empujando el título hacia la derecha. ¿Alguna idea de cómo puedo centrarla?título personalizado del centro en UINavigationBar?

int height = self.navigationController.navigationBar.frame.size.height; 
int width = self.navigationController.navigationBar.frame.size.width; 


UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width + 300, 20)]; 
navLabel.backgroundColor = [UIColor whiteColor]; 
navLabel.textColor = [UIColor redColor]; 
navLabel.font = [UIFont fontWithName:@"Helvetica" size:30]; 
navLabel.textAlignment = UITextAlignmentCenter; 
self.navigationItem.titleView = navLabel; 
[navLabel release]; 
((UILabel *)self.navigationItem.titleView).text = self.title; 

Gracias!

edición me quita código superfluo y ha añadido esta imagen:

Picture of title off ceter

Nótese cómo el título se empuja sobre el botón para acomodar ....

+0

Parece ser un problema de diff. Mi título está centrado verticalmente correctamente. No está centrado horizontalmente correctamente (el botón lo mueve). Si elimino el botón todo se centra perfectamente ... – itgiawa

Respuesta

40

iOS está haciendo esto porque la El marco que inicializas siempre es de 300 píxeles de ancho. Está intentando centrar el fotograma completo, el fotograma es más grande que el espacio en el que quiere colocarlo (debido al botón) y, por lo tanto, su etiqueta se empuja hacia la derecha. Lo que necesita hacer es darle al Frame of the navLabel el tamaño mínimo que necesita.

Por lo tanto, si su texto tiene solo 100 px de ancho, pero el marco es de 400 px, entonces iOS intenta centrar 400 píxeles dentro del encabezado de navegación y no tiene suficiente espacio. Cuando establece el tamaño en 100px real que se necesita, iOS centrará su encabezado correctamente, porque hay mucho espacio para centrar 100px.

El fragmento de código siguiente le ayudará a detectar el tamaño mínimo que necesita su marco, dependiendo de la fuente y el texto que intente colocar. Asegúrese de que el marco de la etiqueta sea lo más pequeño posible, pero no excede el ancho máximo. (el ancho de la barra de navegación).

UIFont* titleFont = [UIFont fontWithName:@"Helvetica" size:30]; 
CGSize requestedTitleSize = [titleText sizeWithAttributes:@{NSFontAttributeName: titleFont}]; 
CGFloat titleWidth = MIN(maxTitleWidth, requestedTitleSize.width); 

UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleWidth, 20)]; 
navLabel.backgroundColor = [UIColor whiteColor]; 
navLabel.textColor = [UIColor redColor]; 
navLabel.font = [UIFont fontWithName:@"Helvetica" size:30]; 
navLabel.textAlignment = NSTextAlignmentCenter; 
navLabel.text = titleText; 
self.navigationItem.titleView = navLabel; 
+1

Nota en iOS 6 y superior UITextAlignmentCenter ha quedado obsoleto. Puede usar NSTextAlignmentCenter en su lugar. – user885232

+0

Gracias, lo he actualizado en la respuesta – Bocaxica

+0

self.navigationItem.titleView - ¡perfecto! – gbk

3

¡Respuesta agradable! Sin embargo, sizeWithFont ahora está en desuso. Querrá hacer algo como esto ahora.

NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:@"Helvetica" size:30], NSFontAttributeName, nil]; 

CGSize requestedTitleSize = [[NSString stringWithFormat:@"Your String"] sizeWithAttributes:textTitleOptions]; 

CGFloat titleWidth = MIN(self.view.frame.size.width, requestedTitleSize.width); 

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleWidth, 44)]; 
5

Tuve el mismo problema antes. Tenía un UINavigationbar con el botón derecho e izquierdo. Quiero centrar una imagen en el UINavigationbar. Así que tuve que poner la imagen en un UIView con width 0. La imagen se obtiene un valor de x que es la mitad del propio width.

UINavigationItem *item = navigationController.topViewController.navigationItem; 
UIView *backView =[[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 30)]; 
[img_logo setFrame:CGRectMake(-45, 5, 90, 20)]; 
[backView addSubview:img_logo]; 
item.titleView = backView; 
+0

Sorprendido de que esto funciona, pero funcionó muy bien para mí. Interesante truco para saber para poder "esconder" una vista dentro de una vista de ancho cero. – anorskdev

2

que utilizan las limitaciones de diseño automático para resolver este problema:

  1. Añadir UILabel en un UIView.
  2. Establecer limitaciones de centerx para el UILabel:

    self.titleLabelCenterXConstraint = [NSLayoutConstraint constraintWithItem:self.titleLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f];

  3. En el UIView layoutSubViews para ajustar el centerx valor de desplazamiento:

    - (void)layoutSubviews { [super layoutSubviews]; CGFloat screenCenter = CGRectGetMidX([UIScreen mainScreen].bounds); CGFloat diffCenter = screenCenter - CGRectGetMidX(self.frame); self.titleLabelCenterXConstraint.constant = diffCenter; }

  4. conjunto UIView a navigationItem titleview

+0

Intenté eso. No funcionó. El título no se movía. La compensación se calculó correctamente, como parece. – osxdirk

+0

¿podría compartir su código? –

+1

¡Funciona como un encanto! – odm

1

Swift 2.3:

let tlabel = UILabel(frame: CGRectMake(0, 0, 200, 40)) 
    tlabel.text = self.title 
    tlabel.textColor = UIColor.whiteColor() 
    tlabel.font = UIFont.boldSystemFontOfSize(17) //UIFont(name: "Helvetica", size: 17.0) 
    tlabel.backgroundColor = UIColor.clearColor() 
    tlabel.adjustsFontSizeToFitWidth = true 
    tlabel.textAlignment = .Center 
    self.navigationItem.titleView = tlabel 
0

El título no está centrada en la propia barra de navegación. Está centrado entre los botones de la izquierda y los botones de la derecha de la barra de navegación. Esto significa que si tiene un botón grande a la izquierda, el título se desplazará hacia la derecha.

Usted puede cambiar el centro mediante la adición de una restricción centrada a su título y luego modificarlo por lo que es realmente el centro de la barra de navegación:

// Position the title in the middle of the navbar and not in the middle of buttons 
fileprivate func centerTitle() { 
    if let navigation = self.navigationController { 
     let titleMiddle = navigation.navigationBar.convert(titleViewLabel.frame, from: titleViewLabel.superview).midX 
     let diff = navigation.navigationBar.center.x - titleMiddle 
     constraintTitleViewCentered.constant += diff 
    } 
} 
1

Swift 3 para la respuesta de @ BHuelse:

let image = UIImage(named: "logo") 
let logoView = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 30)) 
let imageView = UIImageView(frame: CGRect(x: -45, y: 5, width: 90, height: 20)) 
imageView.image = image 
imageView.contentMode = .scaleAspectFit 
logoView.addSubview(imageView) 
self.navigationItem.titleView = logoView 
Cuestiones relacionadas