iphone - superior - Ocultando la barra de herramientas de UINavigationController durante la visualización, no aparecerá:
no me aparece la barra de arriba iphone (11)
El problema aquí es que el UITableView
del UITableView
está configurado para que no se superponga con el UIToolbar
. Es decir, se encuentra justo encima del UIToolbar
. Cuando empuja el siguiente UIViewController
a la pila UINavigationController
, mientras quita la UIToolbar
la UIToolbar
, no hay nada que mostrar excepto la UIWindow
detrás de ella, a menos que ponga algo allí en su lugar .
Una solución alternativa sin la incómoda animación después de la transición es colocar su UITableView
en un "contenedor" UIView
que comparta el mismo marco que su vista normal, pero que se UIToolbar
con el color deseado que desea ver durante la transición (p. Ej., Blanco).
Para promulgar la subincidencia, puede configurar su UIViewController
en wantsFullScreenLayout = YES
. Luego, debe asegurarse de que su UITableView
tenga el mismo marco que tendría antes del uso del contenedor. es decir, se encuentra debajo de la barra de navegación y encima de la barra de herramientas.
Esto se puede hacer más elegante al escribir un UIViewController
personalizado y usarlo en lugar del UITableViewController
, o ser astuto e insertar el nuevo "contenedor" de UITableView
debajo del UITableView
en su actual UITableViewController
.
Tengo una aplicación para iPhone con un menú de UITableView
. Cuando se selecciona una fila en la tabla, el controlador de vista apropiado se inserta en la pila UINavigationController
la aplicación.
Mi problema es que MenuViewController
no necesita una barra de herramientas, pero UIViewControllers
lo hacen los UIViewControllers
que se UIViewControllers
en la pila. Cada UIViewController
que recibe llamadas setToolbarHidden:animated:
in viewDidAppear:
Para ocultar la barra de herramientas, llamo a setToolbarHidden:animated:
in viewWillDisappear:
Mostrar la barra de herramientas funciona, de modo que cuando aparece la vista empujada, la barra de herramientas se desliza hacia arriba y la vista cambia de tamaño correctamente. Sin embargo, cuando se presiona el botón Atrás, la barra de herramientas se desliza hacia abajo, pero la vista no cambia de tamaño. Esto significa que hay una franja negra en la parte inferior de la vista a medida que la otra vista hace la transición. He intentado agregar la altura de la barra de herramientas a la altura de la vista antes de ocultar la barra de herramientas, pero esto hace que la vista se anime durante el Transición para que todavía haya una barra negra.
Me doy cuenta de que puedo administrar mi propia Barra de herramientas, pero me gustaría usar UINavigationControllers
integrados en la Barra de herramientas para mayor comodidad.
Esta publicación en el foro menciona el mismo problema, pero no se menciona ninguna solución.
Esto es solo una puñalada salvaje en la oscuridad, pero tal vez debería dejar que Runloop se ejecute una vez después de ocultar la barra de herramientas:
[viewController setToolbarHidden:YES animated:YES];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0]];
Estoy de acuerdo con la respuesta de Jeff. Pero hay una falla en la interfaz de usuario si oculto la barra de herramientas en el método -viewDidAppear del viewController a través del cual se insertan diferentes viewControllers.
Para evitar esto, estaba experimentando y descubrí que llamar a -setToolbarHidden en la llamada -viewWillAppear oculta la barra de herramientas, pero como dice la pregunta, la vista expandida no estaría ocupada por las filas de tableview.
Para solucionar este problema, he cambiado al siguiente código y ahora funciona sin la falla:
- (void)viewDidLoad
{
[super viewDidLoad];
.
.
.
[self reframeRowHeight];
[self.menuItemTableView addObserver:self
forKeyPath:@"frame"
options:NSKeyValueObservingOptionNew
context:nil];
[self.menuItemTableView setBounces:NO];
.
.
.
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"frame"])
{
[self reframeRowHeight];
}
}
-(void)reframeRowHeight
{
[self.menuItemTableView setRowHeight:self.menuItemTableView.frame.size.height/self.menuItems.count];
[self.menuItemTableView reloadData];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
.
.
.
// Bad Apple! - http://.com/questions/2339721/hiding-a-uinavigationcontrollers-uitoolbar-during-viewwilldisappear
[self.navigationController setToolbarHidden:YES animated:YES];
.
.
.
}
Intente implementar un UINavigationControllerDelegate y configúrelo en la propiedad delegada de su controlador de navegación. Esto logró para mí lo que estás describiendo en tu publicación, sin artefactos visibles.
El siguiente código asume que secondController se inserta en la vista de navegación por una acción realizada en firstController.
MyNavigationControllerDelegate.h
@interface MyNavigationControllerDelegate : NSObject<UINavigationControllerDelegate> {
}
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
@end
MyNavigationControllerDelegate.m
#import "MyNavigationControllerDelegate.h"
#import "AppDelegate_Shared.h"
@implementation MyNavigationControllerDelegate
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([AppDelegate_Shared sharedDelegate].firstController == viewController ) {
[navigationController setNavigationBarHidden:TRUE];
[navigationController setToolbarHidden:FALSE];
}
}
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([AppDelegate_Shared sharedDelegate].secondController == viewController ) {
[navigationController setNavigationBarHidden:FALSE];
[navigationController setToolbarHidden:TRUE];
}
}
@end
sharedDelegate es solo un método auxiliar:
AppDelegate_Shared.m
+ (AppDelegate_Shared*)sharedDelegate {
return (AppDelegate_Shared*)[[UIApplication sharedApplication] delegate];
}
La administración del estado de la barra de herramientas (es decir, qué VC necesita / no necesita la barra de herramientas) se complica rápidamente.
He tenido éxito en seguir esta regla:
Para cada controlador de vista, en viewWillAppear()
, decida si necesita una barra de herramientas o no, luego llame a navigationController?.setToolbarHidden(true or false, animated: animated)
respectivamente.
De esta manera, cada controlador de vista comienza con el estado correcto de la barra de herramientas y no tiene que preocuparse por "restaurar" el estado de la barra de herramientas cuando se descarta el controlador de vista.
No estaba satisfecho con las respuestas a esta pregunta, así que publiqué la mía: Referencia al controlador de vista de origen y al controlador de vista de destino al mismo tiempo
La respuesta que tengo solucionado mi problema. También puede funcionar para el tuyo (aunque esta pregunta es bastante antigua, pensé que esto podría ayudar a alguien como yo que leyó esta publicación media docena de veces en busca de una pista).
Esto es lo que hice. No sé si los protocolos de marcadores son objetivos idiomáticos-c o no, pero los comparo con atributos como los que usaría en c #, así que tengo este protocolo de marcadores:
@protocol HidesNavigationItem
@end
Agregué UINavigationControllerDelegate a mi AppDelegate. Todavía no estoy seguro de si eso es algo bueno o no. Pensé en mantener esa implementación en otro objeto, pero por ahora, aquí es donde la pongo. Aquí está la implementación:
#pragma mark Navigation Controller Delegate
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[navigationController setNavigationBarHidden:[viewController conformsToProtocol:@protocol(HidesNavigationItem)] animated:animated];
}
De esta manera, puedo configurar mi protocolo de marcador en mi implementación de UIViewController así:
@interface MyViewController : UIViewController <HidesNavigationItem>
Si no tengo esa interfaz, la vuelve a poner.
Finalmente, en mi aplicación appDelegate''s: didFinishLaunchingWithOptions: método, conecto al delegado de la siguiente manera:
if ([self.window.rootViewController isMemberOfClass:[UINavigationController class]])
((UINavigationController*)self.window.rootViewController).delegate = self;
Ahora no consigo cajas negras y ningún gato de Cheshire. Mi solución fue, por supuesto, con respecto a la barra de navegación, pero estoy seguro de que funciona igual para la barra de herramientas. Esto es muy similar a la respuesta de Danra, excepto que obtengo el cuadro negro sin "animado: animado".
Para el UIViewController que no necesita una barra de herramientas cuando se le presiona, puede considerar usar cualquiera
Implementando el método hidesBottomBarWhenPushed para ese UIViewController:
// method to be added to the UIViewController that has no toolbar
- (BOOL) hidesBottomBarWhenPushed {
return YES;
}
O antes de presionar UIViewController, establezca el valor de hidesBottomBarWhenPushed:
viewControllerWithNoToolBar.hidesBottomBarWhenPushed = YES
[self.navigationController pushViewController:viewControllerWithNoToolBar animated:YES];
Para mostrar la barra de herramientas en el nuevo controlador de vista solo agregue esto:
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:animated];
[super viewWillAppear:animated];
}
Para ocultar la barra de herramientas:
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
Al viajar entre pantallas, presione el nuevo controlador de vista con el siguiente código:
SettingsRecordingViewController *vc = [[SettingsRecordingViewController alloc] initWithNibName:@"SettingsRecordingViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
y si tiene un estado diferente de barra de herramientas (oculto / mostrado), se mostrará una bonita animación de ocultar / mostrar barra de herramientas.
Tuve el mismo problema y aquí está la solución que funcionó para mí. Digamos que estás presionando SomeUIViewController
en tu pila de navegación.
Defina este ivar (privado) en la interfaz de SomeUIViewController
:
// keep a reference to the navigation controller for use in viewDidDisappear:(BOOL)animated method
UINavigationController * _navigationController;
Implementar los siguientes métodos de SomeUIViewController
:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// here, your controller still has a reference to self.navigationController
_navigationController = [self.navigationController retain];
}
- (void)viewDidDisappear:(BOOL)animated {
// at this point, self.navigationController = 0x0, so
// use your retained reference to the navigation controller to perform any last minute operations, then release
[_navigationController setToolbarHidden:YES];
[_navigationController release];
[super viewDidDisappear:animated];
}
La idea es que desee ocultar la barra de herramientas que pertenece al controlador de navegación después de que la vista de SomeUIViewController
haya desaparecido. De esta manera, evitará cualquier artefacto de visualización no deseado.
RENUNCIA
Esta es simplemente una respuesta que muestra una solución alternativa para la pregunta formulada. Está destinado únicamente a señalar un detalle del funcionamiento interno del marco. También está pensado como un ejemplo de lo que no se debe enviar a Apple AppStore.
Utilizo una imagen de fondo personalizada para el fondo de la barra de herramientas y una imagen personalizada para el fondo de la tabla. Estaba teniendo el mismo problema con la barra negra en la parte inferior, ya que la vista pasaba de una vista de tabla a otra. Sin embargo, puse el
self.navigationController.toolbar.barStyle = UIBarStyleBlackTranslucent;
en viewDidLoad.
Esto establece la imagen de fondo en el tamaño potencial completo del fondo, que si tuviera una barra de herramientas transparente tendría sentido. Probablemente no sea una buena solución cuando esté usando la barra de herramientas opaca estándar, pero para aquellos que personalicen la barra de herramientas de todos modos, pueden obtener lo mejor de ambos mundos.
Yo también he experimentado este problema. En mi caso, la única forma que encontré para ocultar con éxito la barra de herramientas sin mostrar el fondo de la ventana es llamar a [self.navigationController setToolbarHidden:YES animated:animated]
en el controlador -viewDidAppear:
del controlador de -viewDidAppear:
.