11

La propiedad parentViewController de UIViewController es de solo lectura, pero estoy anidando controles de vista personalizados y me gustaría usar esta propiedad.Cómo configurar parentViewController en UIViewController?

Sin embargo, como es de solo lectura, y no encontré otra forma de establecer esta propiedad, mi pregunta es: ¿cómo hacer configurarlo?

Obviamente, UINavigationController puede establecer la propiedad de alguna manera en -pushViewController, y también puede -presentModalViewController, por lo que debe ser posible.

Soy consciente de que solo puedo agregar mi propia propiedad UIViewController, pero estoy seguro de que parentViewController es, en principio, la propiedad correcta.

+0

Creo que cualquiera que haya votado cada respuesta en este hilo podría dar una razón para ello :) – willcodejavaforfood

+0

No fui yo, pero sospecho que no están de acuerdo con el uso de API privadas, y el consejo de votar para usar API privadas parece ser común en SO. Quizás sean lunares de Apple. –

Respuesta

1

Sin embargo, dado que es de solo lectura, y no encontré otra forma de configurar esta propiedad, mi pregunta es: ¿cómo la configuro?

Si es readonly, no puede usar la notación de puntos sin obtener un compiler error.

Sin embargo, es posible que pueda utilizar categories para agregar un método modifyParentViewController personalizado a la clase UIViewController.

Incluso si la propiedad es de solo lectura, la variable en sí podría ser modificable, si no es @protected. Si es @protected, la creación de una subclase del controlador de vista puede permitirle la opción de modificar la variable.

+0

Hacer esto es demasiado sucio para mi gusto, pero supongo que si insistiera en usar parentViewController, esta sería la única manera posible.
Aunque usaré una propiedad UIViewController personalizada. – mrueg

0

parentViewController es para fines de NavigationViewControllers y presenta controladores de vista modal, no hay forma de establecer la propiedad sin los métodos pushViewController o presentModalViewController. ParentViewController es una propiedad de solo lectura que solo puede leerse mediante la clase UIViewController y la clase UINavigationController, las subclases de estas no tendrán acceso para establecer la propiedad.

2

Probé la sugerencia de Alex de comprar una categoría para UIViewController, y funcionó en el simulador, pero no en mi teléfono. aquí es la categoría

@interface UIViewController (parentSetter) 
-(void)setParentUIViewController:(UIViewController*)parent; 
@end 

@implementation UIViewController (parentSetter) 
-(void)setParentUIViewController:(UIViewController*)parent 
{ 
_parentViewController = parent; 
} 
@end 

Se compila y funciona bien, pero tenga en cuenta el miembro subrayado que es un poco desagradable. Eso es lo que causa el error del vinculador al compilar contra el SDK 3.0.

Tengo una vista de contenedor que tiene 2 subvistas y una tabla es una de ellas. La tabla necesita un padre para que pueda interactuar con la barra de navegación, entre otras cosas.

Voy con esta solución en su lugar:

@interface AdoptedTableViewController : UITableViewController { 
    UIViewController* surrogateParent; 
} 

-(UINavigationController*)navigationController; 
@property (nonatomic, assign) IBOutlet UIViewController *surrogateParent; 
@end 

@implementation AdoptedTableViewController 
@synthesize surrogateParent; 

-(UINavigationController*)navigationController 
{ 
    if([super navigationController])//self.navigationController) 
    { 
     return [super navigationController]; 
    } 
    else 
    { 
     return surrogateParent.navigationController; 
    } 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

Todos mis controladores de vista tabla son ahora adoptedTableViewControllers. La razón principal por la que necesitan padres es para que puedan enviar controladores de vista a la pila de navegación, de modo que el controlador de navegación los maneje de forma transparente.

Sería bueno si parentViewController no fuera de solo lectura, pero en mi conversación con _parentViewController descubrí que hay más en la jerarquía de ViewController que solo esa propiedad. Creo que podría haber una gran cantidad de relaciones y responsabilidades en esa relación que Apple no ha limpiado lo suficiente para las masas. Por ejemplo, noté un extraño comportamiento de deselección al subir la jerarquía de navegación que no pude solucionar.Quizás los controladores de navegación de UIN reflejan la clase de su controlador superior y se comportan de manera diferente?

En resumen, realmente es de solo lectura y no hay una solución limpia o simple. Usted acaba de llegar a ser un arquitecto al respecto.

0

Parece que llamar al método setParentViewController: funciona.

[childViewController setParentViewController:self]; 

Sin embargo, esto todavía genera un compilador de advertencia. Lo cual, IMO, significa no hacerlo (en su lugar subclasé).

11

solución es:

- (void)setParentController:(UIViewController*)parent{ 
[self setValue:parent forKey:@"_parentViewController"]; 
    } 

No causa problemas con enlazador!

PS: No utilice "setParentViewController" como nombre de método, porque existe este método en la API privada y Apple dicen: "La API no pública que se incluye en su aplicación es setParentViewController :.

Si definió un método en su código fuente con el mismo nombre que la API mencionada anteriormente, le sugerimos modificar el nombre de su método para que no colisione con la API privada de Apple para evitar que su aplicación se marque con futuras presentaciones.

Please resuelva este problema en su próxima actualización ... "

+2

¿No sería esto un rechazo de la tienda de aplicaciones? Esto resuelve algunos de mis problemas de presentación modal, pero da miedo. –

9

Me doy cuenta de que esta pregunta se realizó antes de iOS 5, pero para la referencia, debe usar addChildViewController cuando quiera anidar UIViewControllers. Esto también configurará automáticamente la propiedad parentViewController.

- (void)addChildViewController:(UIViewController *)childController NS_AVAILABLE_IOS(5_0); 

Puede leer más sobre "Creación de contenido personalizado Ver controladores" en Apple.

+1

Esto funciona para mí, establece la propiedad parentViewController en el controlador de vista secundario. No estoy seguro de por qué no es la respuesta aceptada. – KyleStew

Cuestiones relacionadas