2012-01-01 14 views
7

Primero, un poco de fondo. Soy nuevo en el desarrollo de iOS, llevo mucho tiempo en .Net land, y es por eso que incluso estoy haciendo esta pregunta, pero aquí va.Pasar datos de un controlador de vista a otro; iOS <= 4 vs iOS 5

La configuración básica es esta. Tiene un UINavigationController con un RootViewController llamaremos al MasterViewController. Cuando ocurre alguna acción en este MasterViewController, queremos profundizar en un DetailsViewController. Sin embargo, también queremos pasar algunos datos al DetailsViewController.

es mi entendimiento, que en las versiones anteriores del SDK (antes de IOS 5) el enfoque era similar a esto:

@implementation MasterViewController 

    -(IBAction)someAction 
    { 
     DetailsViewController *dvc = [[DetailsViewController alloc]initWithNibName:@"DetailsView" bundle:nil]; 
     dvc.someDataProp = [self getSomeDataSomeHow]; 
     [[self navigationController] pushViewController:dvc animated:YES]; 
    } 

@end 

Ahora, sin embargo, en IOS 5, parece que esto se hace ahora usando Storyboard y segues. En XCode se configura la segue de la MasterViewController a la DetailsViewController, y luego en el código que hace algo como esto:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    [segue.destinationViewController setSomeDataProp:[self getSomeDataSomeHow]]; 
} 

Mi pregunta es básicamente el siguiente: El enfoque antiguo de alguna manera se siente mucho más limpio para mí. Estás siendo muy explícito sobre el tipo de ViewController que estás presionando en la pila de navegación y puedes establecer propiedades fácilmente en él. Sin embargo, en el nuevo enfoque, destinationViewController es del tipo id (por razones obvias), y me parece mucho menos limpio. De nuevo, este podría ser mi lado .Net que sale, pero ¿es esto común en iOS? ¿Solo usas id y lanzas precaución al viento?

+1

Mucho respeto por preguntar cómo se hace esto en lugar de simplemente copiar y pegar fragmentos. También tuve preguntas similares y con algo de experiencia aquí está mi respuesta: con iOS5, veo que la lógica de la interfaz de usuario se ha dividido en dos: 1) Ciclo de vida y transiciones de ViewController 2) Flujo de datos.Storyboard se ocupa de 1 y se espera que los desarrolladores se encarguen de 2. En tal escenario, estos lanzamientos ocurrirán. Para mí, la pregunta es, ¿esta división tiene sentido? ¿Pueden estos dos conceptos estar desacoplados? Supongo que Apple va por ese camino y veremos cómo funciona. – Guven

Respuesta

6

Con Storyboards puede asignar un identificador con nombre al segue, Seleccione el segue y en el inspector de atributos puede agregar un nombre al identificador de segue.

Y en el método prepareForSegue debe verificar este Identificador y así sabrá explícitamente qué segue está a punto de realizarse y cuál será el destinationViewController.

if ([segue.identifier isEqualToString:@"My First Segue Identifier"]) 
{  
    DetailsViewController *dvc = (DetailsViewController *) segue.destinationViewController; 
    // Set the DVC's properties 
} 
+0

Mejor, pero todavía tienes ese feo elenco allí. ¿Es ese el enfoque preferido? – BFree

+0

Ese es el enfoque preferido. Tienes razón, el viejo modo es más claro y más explícito. Con el nuevo método estás "enganchando" al guión gráfico. Desafortunadamente, hay nuevas funciones que solo se encuentran en los guiones gráficos que no llegaron al diseñador de XIB, como el nuevo soporte de diseñador de UITableView estático y dinámico. –

+1

¿este fragmento de código está insertado dentro del método 'prepareForSegue'? – chwi

4

En muchos casos, el controlador de vista de destino para un segue puede ser un UINavigationViewController, y en ese caso, la solución (una ligera modificación de la solución de Dennis Mathews' arriba) tendrá que utilizar el mensaje 'topViewController' :

if ([segue.identifier isEqualToString:@"My First Segue Identifier"]) 
{  
    NavitationViewController* navController = [segue destinationViewController]; 
    DetailsViewController *dvc = (DetailsViewController*) [navController topViewController] 
    // Set the DVC's properties 
} 
+0

Esto funcionó para mí, excepto que creo que se refiere a "UINavigationController * navController" en lugar de a "NavitationViewController * navController". – mpemburn

1

no he estado trabajando con iOS tanto tiempo, pero he visto algunos ejemplos en los que no tienen que desechar debido al sistema de mensajería flexible, acompañada de Objective-C.

En lugar de comprobar el identificador segue o lanzar a un ViewController específica se puede hacer esto:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.destinationViewController respondsToSelector: @selector(setCompany:)]) { 
     [segue.destinationViewController performSelector: @selector(setCompany:) withObject: self.company]; 
    } 
} 

En la primera línea me pregunte si el destinationViewController tiene una setCompany método (si usted tiene una propiedad denominada compañía este uno se generaría para ti). Si lo hace, puede llamar a ese método/establecer esa propiedad con la segunda línea de código.

Por lo tanto, en este caso no es necesario que conozca realmente el destino ViewController y podría reemplazarlo fácilmente por uno diferente que admita el manejo de empresas.

Cuestiones relacionadas