web-dev-qa-db-fra.com

Affichage du conteneur de storyboard xcode - Comment accéder au viewcontroller

J'essaie d'utiliser le storyboard et de faire fonctionner les choses correctement. J'ai ajouté une vue conteneur à l'une de mes vues existantes. Lorsque j'essaie d'ajouter une référence à cela dans mon contrôleur de vue .h fichier (ctrl-glisser), j'obtiens un IBOutlet UIView *containerView. Comment puis-je obtenir une référence au contrôleur de vue de la vue de conteneur à la place? J'ai besoin du contrôleur de vue de conteneur pour pouvoir définir son délégué sur le contrôleur de ma vue afin qu'ils puissent "parler" entre eux.

J'ai ma configuration de storyboard comme:

enter image description here

Et son référencé dans mon fichier .h comme:

enter image description here

Remarquez dans le .h qui est un UIView, pas mon InstallViewController pour la vue. Comment ajouter une référence au contrôleur de vue? J'ai besoin de pouvoir définir son délégué.

48
Justin808

Il existe une autre solution en spécifiant un identifiant pour la ou les séquences intégrées et en récupérant les contrôleurs de vue correspondants dans la méthode prepareForSegue:

L'avantage de cette méthode est que vous n'avez pas besoin de vous fier à un ordre spécifique dans lequel vos contrôleurs de vue enfant sont ajoutés, car chaque contrôleur de vue enfant est intégré via un identifiant de séquence unique.

Mise à jour 2013-01-17 - Exemple

- (void) prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
    // -- Master View Controller
    if ([segue.identifier isEqualToString:c_SegueIdEmbedMasterVC])
    {
        self.masterViewController = segue.destinationViewController;
        // ...
    }
    // -- Detail View Controller
    else if ([segue.identifier isEqualToString:c_SegueIdEmbedDetailVC])
    {
        self.detailViewController = segue.destinationViewController;
        // ...
    }
}

c_SegueIdEmbedMasterVC & c_SegueIdEmbedDetailVC sont des constantes avec l'ID correspondant des ID de séquence définis dans le storyboard.

69
DAXaholic

Lorsque vous ajoutez une vue de conteneur, le xcode appelle la méthode UIViewController addChildViewController:

Dans votre cas, vous pouvez obtenir le conteneur ViewController le recherchant dans la liste SplashViewController de childViewControllers, quelque chose comme ceci:

for (UIViewController *childViewController in [self childViewControllers])
{
    if ([childViewController isKindOfClass:[InstallViewController class]])
    {
        //found container view controller
        InstallViewController *installViewController = (InstallViewController *)childViewController;

        //do something with your container view viewcontroller

        break;
    }
}

J'ai eu le même doute hier :)

14
vfranchi

La réponse de Vitor Franchi est correcte mais pourrait être plus performante et pratique. Surtout lorsque vous accédez plusieurs fois au contrôleur de vue enfant.

Créer une propriété en lecture seule

@interface MyViewController ()
@property (nonatomic, weak, readonly) InstallViewController *cachedInstallViewController;
@end

Créez ensuite une méthode getter pratique

- (InstallViewController *)installViewController
{
    if (_cachedInstallViewController) return _cachedInstallViewController;

    __block InstallViewController *blockInstallViewController = nil;
    NSArray *childViewControllers = self.childViewControllers;
    [childViewControllers enumerateObjectsUsingBlock:^(id childViewController, NSUInteger idx, BOOL *stop) {

        if ([childViewController isMemberOfClass:InstallViewController.class])
        {
            blockInstallViewController = childViewController;
            *stop = YES;
        }
    }];

    _cachedInstallViewController = blockInstallViewController;

    return _cachedInstallViewController;
}

A partir de maintenant, accédez au contrôleur de vue enfant de cette façon

[self.installViewController doSomething];
2
Martin Stolz
UIView* viewInsideOfContainer = installerView.subviews[0];

Vous donnera l'UIView à l'intérieur de l'UIViewController que votre contrôleur UIView référence. Vous pouvez convertir la sous-vue en n'importe quel type héritant d'UIView.

0
John Verco

Si la nib est chargée, elle appellera addChildViewController dans le cadre du processus d'initialisation

donc une solution performante pourrait être aussi d'écraser

- (void)addChildViewController:(UIViewController *)childController

là, vous pouvez attraper votre childController, par exemple en comparant sa classe et l'affecter à une propriété/ivar

-(void)addChildViewController:(UIViewController *)childController
{
    [super addChildViewController:childController];

    if([childController isKindOfClass:[InstallViewController class]])
    {
        self.installViewController = (InstallViewController *)childController;
    }

}

Cela vous évitera d'itérer à travers les childViewControllers.

0
Alexander Ney