objective-c - item - uitabbarcontroller programmatically swift
Cuando se crea "programáticamente" UINavigationController y UITabBarController, ¿cómo trato sus funciones(como viewWillAppear?) (3)
Estoy creando mi Nav y TabBar en el código en el lanzamiento a través de: IN: myAppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// set up a local nav controller which we will reuse for each view controller
UINavigationController *localNavigationController;
// create tab bar controller and array to hold the view controllers
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:4];
// setup the first view controller (Root view controller)
RootViewController *myViewController;
myViewController = [[RootViewController alloc] initWithTabBar];
// create the nav controller and add the root view controller as its first view
localNavigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
// add the new nav controller (with the root view controller inside it)
// to the array of controllers
[localControllersArray addObject:localNavigationController];
// release since we are done with this for now
[localNavigationController release];
[myViewController release];
// setup the first view controller just like the first
ResortsListViewController *resortsListViewController;
resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
resortsListViewController.title = @"Category1";
resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image1.png"];
resortsListViewController.navigationItem.title=@"Category1";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
// setup the second view controller just like the first
ResortsListViewController *resortsListViewController;
resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
resortsListViewController.title = @"Category2";
resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image2.png"];
resortsListViewController.navigationItem.title=@"Category2";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
// setup the third view controller just like the first
ResortsListViewController *resortsListViewController;
resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
resortsListViewController.title = @"Category3";
resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image3.png"];
resortsListViewController.navigationItem.title=@"Category3";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[resortsListViewController release];
// load up our tab bar controller with the view controllers
tabBarController.viewControllers = localControllersArray;
// release the array because the tab bar controller now has it
[localControllersArray release];
// add the tabBarController as a subview in the window
[window addSubview:tabBarController.view];
// need this last line to display the window (and tab bar controller)
[window makeKeyAndVisible];
}
Como ven, estoy reutilizando ResortsListViewController para pantallas de diferentes categorías (resorts con Playas, resorts con piscinas, resorts con barras de espresso) ... ahora, sin molestarme (sonreír) acerca de las tonterías de mis categorías (porque esta es una aplicación de prueba) Necesito hacer varias cosas:
Necesito poder saber qué clic de pestaña provocó que se muestre el ResortsListViewController. Esperaba usar TAG, pero "initWithRootViewController" no tiene el control de "etiqueta". Entonces, si utilizo un nombre de archivo de imagen que es el nombre de la categoría, puedo usar ese nombre de archivo para distinguir categorías ... o incluso el nombre del elemento de navegación. Necesito saber si hay una manera para que ResortsListViewController sepa qué clic de elemento de tabbar ha causado su visualización. Pensé buscar una "acción" que pudiera asignar al elemento tabbar, pero esa no es la forma en que funciona tabbarcontroller.
Al hacer clic de una pestaña a otra, la vista cambia, el título de ResortsListViewController cambia, etc., pero la TABLEVIEW que contiene no borra y muestra ningún dato nuevo. Buscando en la web he encontrado una posible solución:
http://discussions.apple.com/thread.jspa?threadID=1529769&tstart=0
básicamente diciendo:
Para que UINavigationControllers envíe mensajes "viewWill / Did / Appear / Disappear", debe haber recibido "viewWill / Did / Appear / Disappear" de su contenedor.
¿Cuál es el contenedor para mis UINavigationControllers en esta situación? myAppDelegate se define en el archivo .h como:
NSObject <UIApplicationDelegate, CLLocationManagerDelegate>
y no tiene un:
- (void)viewWillAppear:(BOOL)animated {
}
sección. Cuando agrego uno, dice "Es posible que NSObject no responda a -viewWillAppear" en el depurador.
¿Alguna ayuda por ahí?
De acuerdo, aquí va: esta es la respuesta correcta a la pregunta, sin embargo, no terminó siendo tan difícil. Todo lo que tenía que hacer era lo siguiente:
Cree una propiedad en ResortViewController de tipo int con nombre de variable whichChoice (por ejemplo). Luego dirígelo en la configuración del TabBarController a la:
// setup the first view controller just like the first
ResortsListViewController *resortsListViewController;
resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
// START HERE IS THE CHANGE
resortsListViewController.whichChoice = 1;
// END HERE IS THE CHANGE
resortsListViewController.title = @"Category1";
resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image1.png"];
resortsListViewController.navigationItem.title=@"Category1";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
Para saber en qué pestaña se hizo clic cuando my resortsListViewController toma el control, simplemente consulto la variable de clase: whichChoice para obtener la respuesta.
Cosas como esta son tan simples que se saltean sobre ellas. Pensé que tenía que pasar la variable en una acción y especificar dónde iría con el objetivo como lo hace en otros objetos, pero cuando configura las cosas con anticipación, no tiene que hacer eso. Ahora, una vez dicho esto, establecer dinámicamente "whichChoice" no es tan fácil sin pensarlo mucho más ... pero establecerlo en una variable CONOCIDA en la configuración está bien.
Para la respuesta n. ° 2, simplemente puse un estilo variable de IBOutlet en mi clase, lo conecté a la mesa y luego seguí sus instrucciones, porque sin la variable en IBOutlet y conectándolo a la tabla, no hay referencia a la vista de tabla. Por alguna razón, conectar la tabla simplemente a VIEW "Referencing Outlet" y llamar a [self.tableview reloadData]
no hizo el trabajo.
Pero en su mayor parte, sus respuestas fueron correctas y me condujeron en la dirección correcta. Por otro lado, realmente odio que tengas que hacer clic derecho y arrastrar de aquí para allá en IB si tienes un elemento IB que has creado. Debería poder conectarlo en código usando su ObjectId (o algo así). Eso estaría más en línea con los programadores. Sé que IB está hecho para permitir que la programación sea más fácil para los diseñadores , pero gee wilikers ... ¡es difícil de entender! Termino abandonando IB y creando elementos en código la mayor parte del tiempo ... que no sé si es tan rápido de ejecutar. Tiendo a pensar que no ... pero no tengo pruebas de lo contrario.
Visite Cómo agregar UINavigationController mediante programación
Por favor, visite el enlace de arriba y obtenga toda la información sobre UINavigationController.
1) Esto es bastante simple. Debe establecer la propiedad de delegado para UITabBarController. Debería configurar esto para el objeto del controlador que posee su tabbarcontroller (o su delegado de la aplicación si esa es su configuración). Cualquiera que sea el objeto que se establezca como el delegado, entonces recibirá:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
Y
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
para administrar las selecciones de pestañas. Coloque uno de estos métodos en la implementación de cualquier objeto que establezca como delegado (le gustaría que sea el objeto que posee todos los controladores).
2) Si tiene un UIViewController que aparece como una selección de pestañas (como ResortsListViewController), entonces deberá poner el método viewWillAppear en la implementación del controlador usted mismo:
@implementation ResortsListViewController
- (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundle {
...
}
... etc. ....
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[table reloadData];
}
...
@end
Avíseme si malinterpreté la segunda parte de su pregunta.