bar ios objective-c cocoa-touch uinavigationcontroller uinavigationbar

ios - ¿Hay alguna manera de cambiar la altura de un UINavigationBar en Storyboard sin usar un UINavigationController?



uinavigationbar ios (11)

Quiero utilizar una UINavigationBar personalizada en una de mis vistas, que no forma parte de ninguna UINavigationController UINavigationController. Cuando arrastro un UINavigationBar en Storyboard, se muestra así:

Esta barra es 44px, que sería suficiente si la barra de estado no comparte este espacio. Debido a que iOS7 nos permite usar toda la pantalla, incluido el espacio para la barra de estado, UINavigationBar debe tener 64 px de alto, no 44 px.

Si conecto la vista a la jerarquía de UINavigationController , se muestra correcta:

Leí en alguna parte que si el UINavigationBar tiene la propiedad barPosition: set to UIBarPositionTopAttached , entonces la barra sería 64px. Esto es, sin embargo, una propiedad de readonly .

Mis resultados de búsqueda solo han mostrado algo que considero un "trabajo alternativo". Al agregar un UINavigationController inútil ante este UIViewController , puedo pretender tener una jerarquía, y agregará el UINavigationBar con 64px automáticamente.

¿ Realmente no hay forma de tener un ''pícaro'' (sin la ayuda de un controlador de navegación) UINavigationBar que cubra 64px? Si ese es el caso, ¿hay alguna razón válida de por qué?

(No estoy diciendo que UINavigationBar deba ser de 64px por defecto, pero debería haber una opción para él en el inspector)

(También veo que las personas responden con formas programáticas para resolver esto. Aunque estas respuestas funcionan, todavía tendría que diseñar el guión gráfico con eso en mente (una brecha). Lo que quiero saber es si es posible configurar esto en guión gráfico, o mejor dicho, ¿por qué no está permitido?)


¡Puede establecer la propiedad barPosition en UIBarPositionTopAttached otra manera!

  1. Agregue un delegado a su UINavigationBar.
  2. Implement -positionForBar: en la clase de delegado:

    - (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }

La parte superior de la barra de navegación también debe anclarse a la Guía de diseño superior.


@startupThekid:

iOS generará una excepción si intentas cambiar la máscara de aumento automático para un UINavigationBar que es administrado por un UINavigationController.

Sin embargo, el equivalente Swift del código objetivo C que publicaste es:

var navBar = self.navigationController!.navigationBar

en viewDidAppear ():

navBar.setTranslatesAutoresizingMaskIntoConstraints = false

Donde sea que necesite establecer la restricción:

var navBarHeightConstraint = NSLayoutConstraint(item: navBar, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 1, constant: height) self.view.addConstraint(navBarHeightConstraint)

A continuación, podrá modificar la propiedad constante de la restricción según sea necesario para modificar la altura de la barra de navegación, como para cambiar la orientación del dispositivo.



Estaba en el mismo barco y teniendo problemas, pero ahora lo he solucionado. Estoy tratando de hacer lo correcto para evitar establecer explícitamente el marco, lo cual es deseable para futuras pruebas y soporte fácil para diferentes tamaños de dispositivos. En mi caso, quiero una vista web debajo de una barra de navegación.

Estoy configurando mi controlador de vista para que sea un UINavigationBarDelegate e implemente positionForBar: para devolver UIBarPositionTopAttached , como la respuesta del usuario3269713 . Parecía que el otro truco era usar el diseño automático para colocar la barra debajo de la guía superior.

Este fue el código que estaba usando en viewDidLoad después de crear la barra de navegación y la vista web programáticamente, y todavía estaba viendo la barra atascada en la altura 44 pero no pude ver de inmediato por qué:

[navigationBar sizeToFit]; navigationBar.delegate = self; [self.view addSubview:navigationBar]; [self.view addSubview:webView]; id guide = self.topLayoutGuide; NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide); [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[guide][navigationBar][webView]|" options:0 metrics:nil views:viewNamesDict]];

Pero pensé un poco más y jugué con el diseño automático, y resulta que solo eso fue la causa de mi problema. Estaba intentando confiar en las restricciones traducidas de la barra de navegación de su máscara de aumento automático, pero resultó que necesitaba definirlas explícitamente. Aquí está mi nuevo código viewDidLoad que funciona:

[navigationBar sizeToFit]; navigationBar.delegate = self; navigationBar.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:navigationBar]; [self.view addSubview:webView]; id guide = self.topLayoutGuide; NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide); [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[navigationBar]|" options:0 metrics:nil views:viewNamesDict]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]]; NSString *verticalLayoutVisualExpression = [NSString stringWithFormat:@"V:|[guide][navigationBar(%f)][webView]|", navigationBar.frame.size.height]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalLayoutVisualExpression options:0 metrics:nil views:viewNamesDict]];

Y sí, como esperaba, esto mueve automáticamente la barra al cambiar al paisaje y se oculta la barra de estado.

(Recomiendo encarecidamente un ayudante de diseño automático como Masonry que hace que el código de diseño sea más conciso, y Masonry, por ejemplo, se encarga de desactivar translatesAutoresizingMaskIntoConstraints por usted)


Estoy usando un UINavigationBar independiente también y me encontré con el mismo problema, y ​​encontré que hay dos maneras de corregir esto correctamente.

Lo arreglé usando restricciones y un UIView padre. Establecí esta UIView en el guión gráfico como vista principal de mi UINavigationBar con un marco {0, 0, 320, 64}. Puede agregar una restricción o un conjunto de restricciones que obliguen a UINavigationBar a tener el tamaño deseado. Y dado que su UIView padre tiene el fotograma correcto en su guión gráfico, puede distribuir como siempre sus otras vistas en su guión gráfico.

Ahora bien, si el diseño automático está desactivado, puede cambiar la altura de la barra programáticamente tal como se describe en la respuesta de Lindsey. -(void)viewDidLayoutSubviews parece ser un buen lugar para hacerlo.


Hay una manera de lograr esto SIN usar un UINavigationController o configurarlo mediante programación. Simplemente configure una restricción de altura en la barra de navegación a lo que desee, 64 en este caso.

Puedes lograr lo mismo programáticamente como tal:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:navigationBar attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:64.0f]];

EDITAR:

Como @ @ nerdist-colony señaló, cuando se trabaja con Autolayout siempre ha sido establecer la translatesAutoresizingMaskIntoConstraints AtrasingAutoresizingMaskIntoConstraints a NO contrario puede haber conflictos en las restricciones.


He escrito una publicación en el blog que detalla cómo hacer esto con una intervención mínima del código. Su barra mostrará un espacio en el guión gráfico, pero funcionará bien en el dispositivo. En resumen, los pasos son:

1) Agregue la barra de navegación al controlador de vista en el guión gráfico.

2) Establezca las restricciones para la barra de navegación en el guión gráfico:
- Barra de navegación.Top = Guía de diseño superior.Bottom
- Barra de navegación.Línea = Supervisión.Línea
- Barra de navegación.Trailing = Superview.Trailing

3) Conecte la barra de navegación del guión gráfico a su controlador de vista como @IBOutlet.

4) En la clase del controlador de vista, agregue un protocolo UINavigationBarDelegate a la declaración de clase.

5) En el método viewDidLoad del controlador de vista, establezca el delegado de la barra de navegación en self.

6) En el controlador de vista, agregue el método positionForBar del delegado de posicionamiento de barras. Devuelve UIBarPosition representando TopAttached. (Nota: UINavigationBarDelegate hereda este método de UIBarPositioningDelegate).

La publicación completa con imágenes GIF está aquí:
Utiliza fácilmente una barra de navegación sin un controlador de navegación correspondiente

Estos pasos funcionan a partir de Swift 2.1 / Xcode 7.2


Puede cambiar la altura de la barra de navegación mediante programación:

[navBar setFrame:CGRectMake(0, 0, 320, 64)];

Editar: Como escribí en los comentarios, es posible que deba poner esta línea en viewDidLayoutSubviews para evitar el ajuste automático.



Sé que esta es una forma muy hacky de hacer esto, pero para mí funcionó. Tengo un NavigationViewController y quiero cargar un ViewController modalmente que tiene una UINavigationBar en la parte superior con los botones Listo y Cancelar. Esto es lo que parecía:

Como puede ver, hay una banda blanca en la parte superior que quiero que sea del mismo color que UINavigationBar . En lugar de cambiar la altura de UINavigationBar programación, acabo de crear una nueva vista y establecer el color de fondo igual al de UINavigationBar (HEX = F8F8F8, RGBA = 248,248,248,1.0). Una vez más, sé que esto es súper hacky, pero hace el trabajo por mí. Esto es lo que parece ahora


Si usa el diseño automático, puede establecer la restricción de Height of UINavigationBar en 64 o evento más.