recuperar rapido herramientas como barra acceso ios iphone objective-c ios7 uinavigationcontroller

ios - rapido - como recuperar la barra de herramientas en excel 2007



En iOS 7, presionar un controlador con una barra de herramientas deja un espacio de espacio inutilizable si finalmente está contenido dentro de un controlador de barra de pestañas (14)

En mi aplicación de iOS, el control raíz de mi ventana es un controlador de la barra de pestañas con una jerarquía como esta:

  • UITabBarController
    • UINavigationController 1
      • FirstContentController
    • UINavigationController 2
      • ...
    • UINavigationController 3
      • ...
    • ...

Cuando el usuario toca una determinada fila en FirstContentController , una instancia de SecondController se SecondController en su controlador de navegación. SecondContentController establece hidesBottomBarWhenPushed en YES en su método init y establece self.navigationController.toolbarHidden en NO en viewWillAppear:

En iOS 6, el usuario FirstController la fila en FirstController y SecondController se SecondController en el controlador de navegación. Debido a que ha hidesBottomBarWhenPushed set, ocultaría la barra de pestañas y, para cuando se completara la animación de transición, SecondController estaría en la pantalla con su barra de herramientas visible.

Sin embargo, al probar esto bajo iOS 7, el comportamiento de hidesBottomBarWhenPushed parece haber cambiado. Lo que veo ahora es:

  • La barra de pestañas se oculta, como se esperaba.
  • La barra de herramientas aparece, como se esperaba.
  • un espacio de espacio inutilizable de exactamente 49 píxeles de altura (la altura de la barra de pestañas) aparece entre la barra de herramientas y la vista de contenido

La brecha es completamente inutilizable: no responde a los toques y si configuro clipsToBounds en YES en la vista principal, no se dibuja nada allí. Después de una gran cantidad de depuración y examen de jerarquías de subvistas, parece que el mecanismo de autoajuste de iOS cambia el tamaño de la vista del controlador de vista a una altura de 411 (en el iPhone 5). Debería ser 460 para llegar hasta la barra de herramientas, pero el sistema de diseño parece incluir una barra de pestañas de 49 píxeles de alto "fantasma".

Este problema solo ocurre si el controlador de vista tiene un controlador de barra de pestañas como uno si sus contenedores principales.

En iOS 7, ¿cómo puedo hacer que la barra de pestañas desaparezca y que una barra de herramientas se deslice a la perfección en su lugar cuando se empuja un nuevo controlador, y que la vista ocupe todo el espacio entre el elemento de navegación y la barra de herramientas?

ACTUALIZAR

Después de una investigación adicional, esto solo sucede si los aristasPorExtendidosLayout de edgesForExtendedLayout se establecen en UIRectEdgeNone . Sin embargo, a menos que establezca esa propiedad en UIRectEdgeNone , el marco de la vista es demasiado largo y se extiende bajo la barra de herramientas, donde no se puede ver ni interactuar con ella.


¿Ha intentado mover su llamada hidesBottomBarWhenPushed en la viewDidLoad o antes de que se presione el segundoViewController?

Con ios7, aparecen muchos problemas de tiempo si no hace las llamadas en el momento oportuno.


Como @Leo Natan está señalando, parece que no se recomienda ocultar la barra de pestañas y mostrar una barra de herramientas. Sin embargo, hay una solución muy fácil que está funcionando:

Simplemente marque "Bajo Barras opacas" en las propiedades del controlador de vista en el guión gráfico como se muestra a continuación:


Construí un nuevo proyecto usando tu Gist, y encajé el UITabBarController en un UINavigationController:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; UITabBarController* tabController = [[UITabBarController alloc] init]; tabController.viewControllers = @[ [[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] init]], [[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] init]] ]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tabController]; [navController setNavigationBarHidden:YES]; self.window.rootViewController = navController; return YES; }

Y para mostrar el SecondViewController, aquí está lo que hice:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { SecondViewController* controller = [[SecondViewController alloc] init]; // Reaching the UITabBarViewController''s parent navigationController [self.parentViewController.navigationController pushViewController:controller animated:YES]; }

Finalmente, en el secondViewController:

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.view.backgroundColor = [UIColor redColor]; self.view.clipsToBounds = YES; // The following line only works in iOS7 if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { self.edgesForExtendedLayout = UIRectEdgeNone; } [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil]]; UIBarButtonItem * logoutButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:nil action:nil]; NSMutableArray * arr = [NSMutableArray arrayWithObjects:logoutButton, nil]; [self setToolbarItems:arr animated:YES]; [self.navigationController setNavigationBarHidden:NO animated:YES]; [self.navigationController setToolbarHidden:NO animated:YES]; } - (void)viewWillDisappear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:YES]; [self.navigationController setToolbarHidden:YES animated:YES]; }

Esto es lo que parece:

EDIT: Cambió el ejemplo y cambió la captura de pantalla. Hecho el ejemplo compatible con iOS6.


Creo que puedes establecer los bordes de SecondController para el texto extendido en UIRectEdgeBottom.


Desmarque "Ocultar barras de fondos al presionar" y configure sus autocontroles como si hubiera una barra de pestañas. Luego, en "ViewDidLoad" del controlador en el que desea ocultar la barra de pestañas del sistema, coloque el siguiente código.

[self.tabBarController.tabBar setFrame:CGRectZero];

Esto asegura que la barra de pestañas aún acepte la interacción del usuario y que no sea visible para los usuarios. (otras alternativas, como configurarlo en 0 alfa u oculta, harán inútil la barra de pestañas). Ahora, los autoconocios se asegurarán de que su vista se muestre correctamente con la altura de la barra de pestañas como cero.


Encontré que agregar las siguientes 2 líneas de código en viewDidLoad de SecondViewController (donde desea ocultar TabBar pero mostrar la barra de herramientas) soluciona el problema.

self.extendedLayoutIncludesOpaqueBars = YES; self.edgesForExtendedLayout = UIRectEdgeBottom;

Mi viewDidLoad de SecondViewController es el siguiente:

- (void)viewDidLoad { [super viewDidLoad]; // These 2 lines made the difference self.extendedLayoutIncludesOpaqueBars = YES; self.edgesForExtendedLayout = UIRectEdgeBottom; // The usual configuration self.navigationController.navigationBar.barStyle = UIBarStyleBlack; self.navigationController.navigationBar.translucent = NO; self.navigationController.toolbarHidden = NO; self.navigationController.toolbar.barStyle = UIBarStyleBlack; self.navigationController.toolbar.translucent = NO; . . }

Pero debe corregir el marco de la vista manualmente, ya que esto hace que el tamaño sea (320x504). Lo que significa que se extiende incluso detrás de la barra de herramientas. Si esto no es una preocupación para usted, entonces esta solución debería funcionar.


Es un error en iOS 7 UIKit debido a esta combinación particular de:

  • UITabBarController
  • hidesBottomBarWhenPushed = YES
  • edgesForExtendedLayout = UIRectEdgeNone
  • Barra de herramientas de UINavigationController

Debe presentar un error en Apple e incluir su código de muestra.

Para solucionar el error debe eliminar una de esas cuatro condiciones. Dos opciones probables:

  1. Corrija el diseño de su "segundo" controlador de vista para que funcione correctamente cuando edgesForExtendedLayout se establece en UIRectEdgeAll . Esto podría ser tan simple como configurar el contentInset en una vista de desplazamiento.

  2. No utilice la barra de herramientas incorporada de UINavigationController. En su lugar, cree una instancia de UIToolBar separada y agréguela manualmente a la vista de su segundo controlador de vista.


Esto me ayuda a: Elegir que vea el controlador en el guión gráfico -> Ir a propiedades -> Desmarcar "Ajustar inserciones de vista de desplazamiento"


Gestiono manualmente el ocultar / mostrar de la barra de pestañas inferior junto con la animación de atenuación mediante

... [self.tabBarController.tabBar setHidden:NO]; [self.tabBarController.tabBar setAlpha:0.1]; [UIView animateWithDuration:0.2 animations:^{ [self.tabBarController.tabBar setAlpha:1.0]; }]; ...

La barra de herramientas inferior en SecondVC se agregó en IB. No hay problema hasta ahora. Utilizando Storyboard.


La clave de este dilema es que el tamaño del control de navegación no se modifica. Ir de la esencia de Batkin aquí es una esencia propia .

FirstViewController.m

#import "FirstController.h" #import "SecondController.h" @implementation FirstController -(id)init { if( (self = [super init]) ) { self.tabBarItem.title = @"Foo"; self.tabBarItem.image = [UIImage imageNamed:@"Tab Icon.png"]; } return self; } -(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { return 1; } -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; cell.textLabel.text = @"Click"; return cell; } -(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { SecondController* controller = [[SecondController alloc] init]; self.tabBarController.tabBar.hidden = YES; [self.navigationController pushViewController:controller animated:YES]; } @end

SecondViewController.m

#import "SecondController.h" @implementation SecondController -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.view.backgroundColor = [UIColor redColor]; self.view.clipsToBounds = YES; /* ENTER VORTEX OF DESPAIR */ // without this, there''s no gap, but the view continues under the tool // bar; with it, I get the 49-pixel gap thats making my life miserable self.edgesForExtendedLayout = UIRectEdgeNone; //this resizes the navigation controller to fill the void left by the tab bar. CGRect newFrame = self.navigationController.view.frame; newFrame.size.height = newFrame.size.height + 49; self.navigationController.view.frame = newFrame; /* EXIT VORTEX OF DESPAIR */ self.navigationController.toolbarItems = @[ [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil] ]; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.navigationController.toolbarHidden = NO; // will log a height of 411, instead of the desired 460 NSLog(@"frame: %@", NSStringFromCGRect(self.view.frame)); NSLog(@"frame: %@", NSStringFromCGRect(self.navigationController.view.frame)); } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.tabBarController.tabBar.hidden = NO; self.navigationController.toolbarHidden = YES; //this resizes the navigation controller back to normal. CGRect newFrame = self.navigationController.view.frame; newFrame.size.height = newFrame.size.height - 49; self.navigationController.view.frame = newFrame; //this is optional and resizes the view to fill the void left by the missing toolbar. CGRect newViewFrame = self.view.frame; newViewFrame.size.height = newViewFrame.size.height + 49; self.view.frame = newViewFrame; } @end


Si está utilizando Diseño automático, asegúrese de fijar la vista en su vista de supervisión en lugar de en la Guía de diseño superior o en la Guía de diseño inferior.


Tiene que configurar la tabBar de tabBar del tabBar de tabBar de TabBarController como hidden y su vista debería tener el autosizing en altura flexible.

Con este código está funcionando:

@implementation SecondController -(id)init { if( (self = [super init]) ) { } return self; } - (void)viewDidLoad; { [super viewDidLoad]; self.view.backgroundColor = [UIColor redColor]; self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.tabBarController.tabBar.hidden = YES; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // will log a height of 411, instead of the desired 460 NSLog(@"frame: %@", NSStringFromCGRect(self.view.frame)); } @end

O, si desea usar el método hidesBottomBarWhenPushed , debe hacer esto antes de presionar el controlador de vista obviamente:

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { SecondController* controller = [[SecondController alloc] init]; controller.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewController:controller animated:YES]; }

Si usa el segundo método, su método viewDidLoad puede deshacerse del método de altura flexible así como de tabBarHidden:

- (void)viewDidLoad; { [super viewDidLoad]; self.view.backgroundColor = [UIColor redColor]; self.edgesForExtendedLayout = UIRectEdgeNone; }

Vea el resultado:


Usted menciona que puede solucionar este problema al no tocar el edgesForExtendedLayout . ¿Hay alguna razón necesaria para que el contenido / los controles del controlador de vista estén contenidos en la vista raíz del controlador de vista insertado? Podría considerar envolver todo en una vista que sea el primer y único elemento secundario de la vista principal. Luego, ajuste el marco de esa vista en viewDidLayoutSubviews del controlador de vista viewDidLayoutSubviews para evitar tener contenido permanentemente debajo de la barra de herramientas usando la guía de puntos superior / inferior del control de vista.


No le va a gustar esta respuesta. Esta no es la respuesta que desea, pero después de algunas investigaciones sobre cómo ocultar la barra de pestañas en iOS7, mi conclusión es: ¡no!

Las barras de pestañas nunca han sido diseñadas para ocultarse; después de todo, ¿por qué tener un UITabBarController si desea ocultar la barra de pestañas? hidesBottomBarWhenPushed en los controladores de vista sirve para ocultar la barra inferior de un controlador de navegación, no las barras de pestañas. De la documentación:

Un controlador de vista agregado como elemento secundario de un controlador de navegación puede mostrar una barra de herramientas opcional en la parte inferior de la pantalla. El valor de esta propiedad en el controlador de vista superior determina si la barra de herramientas está visible. Si el valor de esta propiedad es SÍ, la barra de herramientas está oculta. Si el valor de esta propiedad es NO, la barra es visible.

Además, se le advierte que no modifique el objeto de la barra de pestañas directamente. De nuevo, a partir de la documentación:

Nunca debe intentar manipular el objeto UITabBar almacenado en esta propiedad.

Esto es exactamente lo que estás haciendo cuando lo configuras como oculto.

En iOS6 esto ha funcionado, pero ahora en iOS7 no funciona. Y parece muy propenso a ocultarlo. Cuando finalmente logras ocultarlo, si la aplicación pasa al fondo y regresa, la lógica de diseño de Apple anula los cambios.

Mi sugerencia es mostrar sus datos modalmente. En iOS7 puede crear transiciones personalizadas, por lo que si es importante para usted tener una transición de inserción, puede recrearla usted mismo, aunque esto es un poco exagerado. La transición modal normal es algo que los usuarios conocen, y en realidad se ajusta mejor a este caso que al empujar que oculta la barra de pestañas.

Otra solución es usar una barra de herramientas en lugar de una barra de pestañas. Si usa la barra de herramientas del controlador de navegación para sus pestañas, puede usar hidesBottomBarWhenPushed como necesite y le dará el comportamiento que espera.