2011-11-08 17 views
6

Actualmente agrego un controlador de vista usando pushViewController:animated: y ahora desde dentro de ese nuevo me gustaría llamar a un método dentro de mi "padre" -controlador. Creo que me quedo atrapado en el control de navegación.Llamar a un controlador de vista padre (a través de un controlador de navegación)

Actualmente intentar esto para ver si es el controlador que quiero:

if([self.superclass isKindOfClass:[MySuperController class]]) 
// and tried: 
if([self.presentingViewController isKindOfClass:[MySuperController class]]) 

Ninguno de estos dos funcionó.

¿Cómo puedo acceder al controlador (un método en él) que empujó el actual?

+0

Debería usar declarar un delegado en el segundo controlador de vista e implementarlo en el "ParentViewController" – Marsson

+0

@Marsson, ¿Cómo se vería eso? '' y luego ...? – LouwHopley

Respuesta

37

Al igual que Marsson mencionó, es necesario utilizar delegado ...

Aquí es una muestra:

En el controlador de vista del niño .h archivo:

@protocol ChildViewControllerDelegate <NSObject> 
- (void)parentMethodThatChildCanCall; 
@end 

@interface ChildViewController : UIViewController 
{ 
} 
@property (assign) id <ChildViewControllerDelegate> delegate; 

En su opinión niño archivo de controlador .m:

@implementation ChildViewController 
@synthesize delegate; 


// to call parent method: 
// [self.delegate parentMethodThatChildCanCall]; 

En matriz controlador de vista .h archivo:

@interface parentViewController <ChildViewControllerDelegate> 

En vista de archivos .m controlador de matriz:

//after create instant of your ChildViewController 
childViewController.delegate = self; 

- (void) parentMethodThatChildCanCall 
{ 
    //do thing 
} 
+0

¡Yay! Gracias: D - Llamé al método en el niño usando '[self.delegate myMethod];' – LouwHopley

+0

He estado luchando con esto todo el día hasta que encontré esta respuesta. Se olvidó de configurar el delegado del controlador de visión infantil en sí mismo. Gracias por la respuesta :-). –

+0

¡Gracias por esto! Funcionó como un encanto .. –

1

No estoy seguro de la lógica de su aplicación, pero siempre puede hacerlo.

En su controlador "secundario", declare la propiedad del tipo padre-controlador. Así, en su archivo .h:

MySuperController *superController; 
property(nonatomic, retain)MysuperController *superController; 

y en su archivo .m:

@synthesize superController; 

Antes de "empujar" el controlador de niño:

MyChildController *child = ... 
[child setSuperController:self]; 
[self.navigationController pushViewController:child animated:YES]; 

Luego, en su controlador hijo le puede simplemente acceder a su súper con

I ' No voy a abogar por esta forma de codificación, pero es una forma rápida/barata/sucia de lograr cosas.

+0

Genial, gracias.Justo cuando intento '[child setSuperController: self];' me advierte que trato de enviar 'MySuperController *' en lugar de 'int *' ... ¿raro? – LouwHopley

+0

Ah, no puedo hacer esto. Crea un bucle infinito. (Con ellos importar uno al otro) – LouwHopley

+0

Ver la respuesta del usuario523234 - él es más al grano. –

4
self.navigationController.viewControllers 

Devuelve una matriz de todos los controladores de vista de la pila de navegación. El controlador de vista actual está en la parte superior de la pila, el controlador de vista anterior es el siguiente, y así sucesivamente.

lo tanto, puede hacer lo siguiente:

NSArray *viewControllers =  self.navigationController.viewControllers; 
int count = [viewControllers count]; 
id previousController = [viewControllers objectAtIndex:count - 2]; 
if ([previousController respondsToSelector:@selector(myMethod)]) 
    [previousController myMethod]; 

Si sabe lo que el controlador de clase anterior es que puede echarlo explícitamente en lugar de utilizar ID.

+0

Parece una forma legítima, pero, 'count' es' 0' cuando 'NSLog'. – LouwHopley

+0

Eso sugeriría que el controlador de navegación era nulo, asumí que estaba usando un controlador de navegación de la pregunta, ¿es eso incorrecto? – jrturton

Cuestiones relacionadas