descartarModalViewController Y transferir datos

Tengo dos controladores de vista, primero ViewController y secondViewController . Estoy usando este código para cambiar a mi segundo ViewController (también le estoy pasando una cadena):

secondViewController *second = [[secondViewController alloc] initWithNibName:nil bundle:nil]; second.myString = @"This text is passed from firstViewController!"; second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentModalViewController:second animated:YES]; [second release]; 

Luego uso este código en secondViewController para volver al primer ViewController:

 [self dismissModalViewControllerAnimated:YES]; 

Todo esto funciona bien. Mi pregunta es, ¿cómo pasaría los datos al primer ViewController? Me gustaría pasar una cadena diferente al primer ViewController del segundo ViewController.

Necesita usar protocolos delegates … Aquí le mostramos cómo hacerlo:

Declare un protocolo en su segundo archivo de encabezado ViewController. Debe tener un aspecto como este:

 #import  @protocol SecondDelegate  -(void)secondViewControllerDismissed:(NSString *)stringForFirst @end @interface SecondViewController : UIViewController { id myDelegate; } @property (nonatomic, assign) id myDelegate; 

No olvides sintetizar myDelegate en tu archivo de implementación (SecondViewController.m):

 @synthesize myDelegate; 

En el archivo de encabezado de FirstViewController, suscríbase al protocolo SecondDelegate haciendo esto:

 #import "SecondViewController.h" @interface FirstViewController:UIViewController  

Ahora cuando crea una instancia de SecondViewController en FirstViewController, debe hacer lo siguiente:

 // If you're using a view controller built with Interface Builder. SecondViewController *second = [[SecondViewController alloc] initWithNibName:"SecondViewController" bundle:[NSBundle mainBundle]]; // If you're using a view controller built programmatically. SecondViewController *second = [SecondViewController new]; // Convenience initializer that uses alloc] init] second.myString = @"This text is passed from firstViewController!"; second.myDelegate = self; second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentModalViewController:second animated:YES]; [second release]; 

Por último, en el archivo de implementación para su primer controlador de vista (FirstViewController.m), implemente el método de SecondDelegate para secondViewControllerDismissed:

 - (void)secondViewControllerDismissed:(NSString *)stringForFirst { NSString *thisIsTheDesiredString = stringForFirst; //And there you have it..... } 

Ahora cuando está a punto de descartar el segundo controlador de vista, desea invocar el método implementado en el primer controlador de vista. Esta parte es simple. Todo lo que haces es, en tu segundo controlador de vista, agregar un código antes del código de descarte:

 if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)]) { [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"]; } [self dismissModalViewControllerAnimated:YES]; 

Los protocolos delegates son EXTREMADAMENTE, EXTREMADAMENTE, EXTREMADAMENTE útiles. Te haría bien familiarizarte con ellos 🙂

NSNotifications es otra manera de hacer esto, pero como una mejor práctica, prefiero usarlo cuando quiero comunicarme a través de múltiples viewControllers u objetos. Aquí hay una respuesta que publiqué antes si tiene curiosidad acerca del uso de NSNotifications: disparar eventos a través de múltiples viewcontrollers desde un hilo en el appdelegate

EDITAR:

Si desea pasar múltiples argumentos, el código antes de cerrar se ve así:

 if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)]) { [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject]; } [self dismissModalViewControllerAnimated:YES]; 

Esto significa que su implementación del método SecondDelegate dentro de su primer ViewController se verá así:

 - (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2 { NSString thisIsTheDesiredString = stringForFirst; NSObject desiredObject1 = inObject1; //....and so on } 

Podría estar fuera de lugar aquí, pero estoy empezando a preferir mucho más la syntax del bloque al enfoque delegado / protocolo muy detallado. Si crea vc2 desde vc1, tenga una propiedad en vc2 que puede establecer desde vc1 que es un bloque.

 @property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response); 

Entonces, cuando algo sucede en vc2 de lo que quieres contarle a vc1, simplemente ejecuta el bloque que definiste en vc1.

 self.somethingHappenedInVC2(@"Hello!"); 

Esto le permite enviar datos de vc2 a vc1. Como la magia. OMI, esto es mucho más fácil / más limpio que los protocolos. Los bloques son increíbles y deben ser adoptados tanto como sea posible.

EDITAR – Ejemplo mejorado

Digamos que tenemos un mainVC que deseamos presentar un modalVC además de temporalmente para obtener información de un usuario. Para presentar ese CV modal desde mainVC, necesitamos asignarlo / iniciarlo dentro de mainVC. Bastante básico. Bueno, cuando hacemos este objeto modalVC, también podemos establecer una propiedad de bloque que nos permita comunicarnos fácilmente entre ambos objetos vc. Tomemos el ejemplo de arriba y pongamos la siguiente propiedad en el archivo .h de modalVC:

  @property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response); 

Luego, en nuestro mainVC, después de haber alojado / iniciado un nuevo objeto modalVC, estableces la propiedad block de modalVC de esta manera:

 ModalVC *modalVC = [[ModalVC alloc] init]; modalVC.somethingHappenedInModalVC = ^(NSString *response) { NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response); } 

Así que solo estamos configurando la propiedad de bloque y definiendo qué sucede cuando se ejecuta ese bloque.

Finalmente, en nuestro modalVC, podríamos tener un tableViewController respaldado por una matriz de cadenas de dataSource. Una vez que se hace una selección de fila, podríamos hacer algo como esto:

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedString = self.dataSource[indexPath.row]; self.somethingHappenedInModalVC(selectedString); } 

Y, por supuesto, cada vez que seleccionamos una fila en modalVC, vamos a obtener una salida de consola de nuestra línea NSLog en mainVC. ¡Espero que ayude!

hmm, busca el centro de notificaciones y devuelve información en una notificación. aquí las manzanas se encargan de esto . Tomo este enfoque personalmente a menos que alguien tenga alguna otra sugerencia

Defina un protocolo de delegado en el segundo controlador de vista y haga que el primero sea el delegado del segundo.