web-dev-qa-db-fra.com

Ajouter un contrôleur de vue enfant au contrôleur de vue actuel

J'essaie d'ajouter un contrôleur de vue enfant dans le code au contrôleur de vue actuel à partir du storyboard en utilisant le code suivant:

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 vue semble au moins s'afficher sur le simulateur mais dans la console, j'obtiens beaucoup ou une erreur:

 <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.

Et aussi la même description mais une erreur différente:

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

toutes ces erreurs sont enregistrées deux fois.

Est-ce que quelqu'un sait ce que je fais mal?

j'ai également lu quelques articles et dans certains, il a été suggéré d'allouer et d'initier le contrôleur de vue avant de transmettre les données, j'ai également essayé cela sans aucune chance.

19
Laur Stefan

didMoveToParentViewController doit être le dernier.

6
kirander

pourquoi vous n'essayez pas ce code pour ajouter une vue je pense que celui-ci est simple et facile ..

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]; 

pour plus d'informations, consultez cette lien .

27
Shahzaib Maqbool
  • Configuration d'un conteneur dans Interface Builder.

Pour créer une relation conteneur parent-enfant au moment de la conception, ajoutez un objet de vue conteneur à votre scène de storyboard, comme illustré dans l'image ci-dessous. Un objet de vue de conteneur est un objet d'espace réservé qui représente le contenu d'un contrôleur de vue enfant. Utilisez cette vue pour dimensionner et positionner la vue racine de l'enfant par rapport aux autres vues du conteneur.

enter image description here

Lorsque vous chargez un contrôleur de vue avec une ou plusieurs vues de conteneur, Interface Builder charge également les contrôleurs de vue enfant associés à ces vues. Les enfants doivent être instanciés en même temps que le parent afin que les relations parent-enfant appropriées puissent être créées.

Si vous n'utilisez pas Interface Builder pour configurer vos relations de conteneur parent-enfant, vous devez créer ces relations par programme en ajoutant chaque enfant au contrôleur de vue de conteneur, comme décrit dans Ajout d'un contrôleur de vue enfant à votre contenu.

  • Ajout d'un contrôleur de vue enfant à votre contenu.

Pour incorporer un contrôleur de vue enfant dans votre contenu par programme, créez une relation parent-enfant entre les contrôleurs de vue appropriés en procédant comme suit:

  1. Appeler le addChildViewController: méthode de votre contrôleur de vue de conteneur. Cette méthode indique à UIKit que votre contrôleur de vue de conteneur gère désormais la vue du contrôleur de vue enfant.
  2. Ajoutez la vue racine de l'enfant à la hiérarchie de vues de votre conteneur. N'oubliez pas de définir la taille et la position du cadre de l'enfant dans le cadre de ce processus.
  3. Ajoutez des contraintes pour gérer la taille et la position de la vue racine de l'enfant.
  4. Appelez la méthode didMoveToParentViewController: du contrôleur de vue enfant.

Voici le code pour cela.

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

Rapide :

func displayContentController(_ content: UIViewController?) {
if let content = content {
    addChild(content)
}
content?.view.frame = frameForContentController()
view.addSubview(currentClientView)
content?.didMove(toParent: self)

}

Une explication plus détaillée du même exemple est donnée dans Guide de programmation pour développeurs Apple .

22
Piyush

Solution dans Swift (Swift 4 au moment d'écrire ces lignes):

//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)

Remarques:

  • Le nom du storyboard est "Main".
  • L'identifiant du contrôleur de vue dans le storyboard est nommé "LOGIN".
  • Cela utilise un storyboard pour créer la charge du contrôleur de vue, mais la même chose peut être effectuée par programme. Assurez-vous simplement que la vue est chargée en mémoire avant d'essayer d'accéder au cadre de la vue ou vous obtiendrez un plantage (faites quelque chose comme présenter le contrôleur de vue de manière modale).
8
jason z