Agregue el controlador de vista hijo al controlador de vista actual

Estoy tratando de agregar un controlador de vista infantil en el código, al controlador de vista actual desde el guión gráfico mediante el siguiente código:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; LogInTutorialViewController *lvc = [[LogInTutorialViewController alloc] init]; lvc = (LogInTutorialViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LogInTutorialViewControllerID"]; [self displayContentController:lvc]; - (void) displayContentController: (LogInTutorialViewController*) content; { //add as childViewController [self addChildViewController:content]; [content didMoveToParentViewController:self]; [content.view setFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)]; [self.view addSubview:content.view]; } 

La vista parece mostrarse en el simulador al menos, pero en la consola obtengo un montón o error:

  : CGContextSaveGState: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update. 

Y también la misma descripción pero diferente error:

CGContextSetLineWidth, CGContextSetLineJoin, CGContextSetLineCap, CGContextSetMiterLimit, CGContextSetFlatness, CGContextAddPath, CGContextDrawPath, CGContextRestoreGState

todos estos errores se registran dos veces.

¿Alguien sabe lo que estoy haciendo mal?

También leí algunas publicaciones y en algunas se sugirió que se asignara e iniciara el controlador de vista antes de pasar los datos, también lo intenté sin suerte.

didMoveToParentViewController debe ser el último.

¿Por qué no prueba este código para agregar vista? Creo que este es simple y fácil.

 self.loginView = [self.storyboard instantiateViewControllerWithIdentifier:@"LOGIN"]; [self addChildViewController:self.loginView]; [self.loginView.view setFrame:CGRectMake(0.0f, 0.0f, self.contentView.frame.size.width, self.contentView.frame.size.height)]; [self.contentView addSubview:self.loginView.view]; [self.loginView didMoveToParentViewController:self]; 

Para más información, consulte este enlace .

  • Configurando un contenedor en Interface Builder.

Para crear una relación de contenedor primario-secundario en el momento del diseño, agregue un objeto de vista contenedor a su escena del guión gráfico, como se muestra en la imagen a continuación. Un objeto de vista de contenedor es un objeto de marcador de posición que representa los contenidos de un controlador de vista secundaria. Use esa vista para dimensionar y ubicar la vista de raíz del elemento secundario en relación con las otras vistas del contenedor.

enter image description here

Cuando carga un controlador de vista con una o más vistas de contenedor, el Generador de interfaz también carga los controladores de vista secundarios asociados con esas vistas. Los hijos deben ser instanciados al mismo tiempo que el padre para que se puedan crear las relaciones padre-hijo apropiadas.

Si no utiliza Interface Builder para configurar sus relaciones de contenedor principal-secundario, debe crear esas relaciones mediante progtwigción agregando cada elemento secundario al controlador de vista de contenedor, como se describe en Agregar un controlador de vista secundaria a su contenido.

  • Agregar un controlador de vista infantil a su contenido.

Para incorporar un controlador de vista secundaria en su contenido mediante progtwigción, cree una relación padre-hijo entre los controladores de vista relevantes haciendo lo siguiente:

  1. Llame al addChildViewController: de su controlador de vista de contenedor. Este método le dice a UIKit que su controlador de vista de contenedor ahora está administrando la vista del controlador de vista secundaria.
  2. Agregue la vista de raíz del niño a la jerarquía de vista de su contenedor. Recuerde siempre establecer el tamaño y la posición del marco del niño como parte de este proceso.
  3. Agregue cualquier restricción para administrar el tamaño y la posición de la vista de raíz del elemento secundario.
  4. Llame al método didMoveToParentViewController: del controlador de vista hijo.

Aquí está el código para eso.

 - (void)displayContentController:(UIViewController *)content { [self addChildViewController:content]; content.view.frame = [self frameForContentController]; [self.view addSubview:self.currentClientView]; [content didMoveToParentViewController:self]; } 

Se proporciona una explicación más detallada del mismo ejemplo en la guía de progtwigción para desarrolladores de Apple .

Solución en Swift (Swift 4 en el momento de escribir esto):

 //load the view controller and add as child storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) loginVC = storyboard.instantiateViewController(withIdentifier: "LOGIN") addChildViewController(loginVC) //make sure that the child view controller's view is the right size loginVC.view.frame = contentView.bounds contentView.addSubview(loginVC.view) //you must call this at the end per Apple's documentation loginVC.didMove(toParentViewController: self) 

Notas:

  • El nombre del guión gráfico es “Principal”.
  • El identificador de controlador de vista en el guión gráfico se denomina “INICIAR SESIÓN”.
  • Esto usa un guión gráfico para crear cargar el controlador de vista, pero lo mismo se puede hacer programáticamente. Solo asegúrese de que la vista esté cargada en la memoria antes de intentar acceder al marco de la vista o se producirá un locking (haga algo como presentar el controlador de vista de forma modal).