web-dev-qa-db-fra.com

Chargement de UIView personnalisé à partir de nib, toutes les sous-vues contenues dans nib sont nulles?

J'ai un objet UIView personnalisé avec un nib qui définit la disposition de la vue/sous-vue. Mes prises sont connectées et lorsque j'initie l'objet à partir de initWithFrame: tout est en ordre.

Le problème que j'ai est quand j'utilise IB pour incorporer le UIView dans une autre plume; le UIView personnalisé apparaît, mais aucune des sous-vues qu'il contient n'apparaît - en fait, leurs symboles sont tous résolus à zéro. J'ai un très minime initWithCoder: et awakeFromNib: implémentation (ne fait que la journalisation) et ma compréhension est que comme la plume est désérialisée, les sous-vues devraient au moins être initialisées pendant le processus?

La seule conclusion à laquelle je parviens par moi-même est que deux choses se produisent: soit mes références de sortie sont corrompues/mauvaises et ne fonctionnent pas, soit ma compréhension du processus de chargement à partir de la pointe est défectueuse et je suis manque quelque chose.

Merci d'avance!

Edit: (Code publié pour Nekto comme demandé ... comme vous le verrez, il enregistre et c'est tout, hein.)

- (id)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super initWithCoder:aDecoder])) {
        NSLog(@"ThumbnailGridView.initWithCoder frame= %f, %f", self.frame.size.width, self.frame.size.height);
    }
    return self;
}

- (void)awakeFromNib
{
    NSLog(@"ThumbnailGridView:awakeFromNib");
}

Edit 2: plumes, contrôleurs, sous-vues, etc.

Plumes: J'ai une seule plume contenant une UIView. Cette vue UIV contient une seule vue UIScrollView, qui est remplie d'une grille de vues UIV définies dans une autre pointe. (Remarque: cette partie fonctionne correctement, car le remplissage est effectué par programme et fonctionne avec un appel initWithFrame:.) Le problème ici est que le symbole UIScrollView est nul après que initWithCoder: et awakeFromNib: sont tous deux appelés, donc les objets sont simplement ajoutés à rien et rien ne se passe. Si le symbole scrollview n'était pas nul, je suis sûr que cela fonctionnerait.

Contrôleurs: il y a deux contrôleurs qui utilisent cela, l'un est fait avec initWithFrame: et fonctionne parfaitement, l'autre l'intègre comme une référence basée sur nib. (Comme mentionné ailleurs ici, définissant une UIView dans IB, définissant la classe personnalisée.) J'ai parcouru le code, et cette vue - étant correctement initialisée - seules ses sous-vues sont "manquantes".

Est-ce que cela aide à donner une image plus claire de la situation?

31
strahlr

Vous vous méprenez peut-être sur le fonctionnement du chargement des plumes. Si vous définissez une UIView personnalisée et créez un fichier nib pour disposer ses sous-vues, vous ne pouvez pas simplement ajouter une UIView à un autre fichier nib, changez le nom de classe dans IB en votre classe personnalisée et attendez-vous à ce que le système de chargement de nib le comprenne. Vous devez modifier initWithCoder de votre classe UIView personnalisée pour charger par programmation la plume qui définit sa disposition de sous-vue. par exemple.:

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil];
        [self addSubview:self.toplevelSubView];
    }
    return self;
}

Le fichier nib de votre vue personnalisée doit avoir la classe "Propriétaire du fichier" définie sur votre classe de vue personnalisée et vous devez avoir une sortie dans votre classe personnalisée appelée "toplevelSubView" connectée à une vue de votre fichier nib de vue personnalisée qui agit comme un conteneur pour toutes les sous-vues. Ajoutez des prises supplémentaires à votre classe d'affichage et connectez les sous-vues au "propriétaire du fichier" (votre UIView personnalisé).

Alternativement, créez simplement votre vue personnalisée par programme et contournez IB.

51
Robin Summerhill

Vérifiez que vous appelez la `` super '' implémentation d'initWithCoder: et awakeFromNib dans chacune de vos méthodes substituées, c'est-à-dire.

- (id)initWithCoder:(NSCoder *)decoder {
    if ((self = [super initWithCoder:decoder])) {
      ...your init code...
    }
    return self;
}

- (void)awakeFromNib {
     [super awakeFromNib];
     ...your init code...
}
5
Robin Summerhill