11
votes

Où initialiser Personnalisé UIView, instancié dans l'interface Builder?

J'ai une sous-classe d'UIView qui est instanciée dans un fichier XIB. J'en ai besoin pour faire une certaine initialisation (Paramètres de variables et créer une sous-vision).

Cependant, je n'ai pas toujours instancier cette vue via Interface Builder. Je le fais de manière programmatique aussi. Dans les deux cas, l'initialisation doit être la même.

Mon initialiseur désigné est initwithvalues: .

La question est; Où puis-je exécuter l'initialisation?

Puisque je dois l'exécuter dans 2 endroits différents, j'ai pensé que je dois le refroidir dans une méthode distincte d'initialisation (ou quelque chose comme ça) et l'appelez à partir de initwithvalues: < / code>.

mais lors du chargement d'IB, les deux initwithcoder: et ewakefromnib sont appelés. De quelle méthode dois-je appeler initialiser ? Ou dois-je appeler initwithvalues: à partir de initwithcoder: et ne rien faire dans ewakefromnib ?


0 commentaires

3 Réponses :


10
votes

Cela dépend de ce que vous devez initialiser. Dès que ewakefromnib est appelé, tous les points de vente et les connexions d'action de votre vue sont établis qui n'est pas le cas dans initwithcoder: . Donc, si vous avez besoin de vous fier à ces connexions, utilisez ewakeffromnib. Sinon, vous pouvez effectuer toute votre initialisation dans initwithcoder: .


0 commentaires

17
votes

Vous devez utiliser initwithframe: code> lors de l'initialisation des vues (puisqu'il s'agit de l'initialiseur désigné). Par conséquent, si vous avez initwithvalues: code> Assurez-vous d'appeler initwithframe: code> de celui-ci.

Quelque chose comme ça devrait fonctionner pour l'initialisation:;) p>

- (void)initialize{
     //init your ivars here
}

- (id)initWithCoder:(NSCoder *)aCoder{
    if(self = [super initWithCoder:aCoder]){
        [self initialize];
    }
    return self;
}

- (id)initWithFrame:(CGRect)rect{
    if(self = [super initWithFrame:rect]){
        [self initialize];
    }
    return self;
}


2 commentaires

N'est-il pas "faux" d'appeler deux initialiseurs différents de la superclasse? Je ne devrais pas appeler l'initialisateur désigné de ma sous-classe ( initwithvalues: ) à partir de initwithcoder: ?


N'est-il pas "faux" d'appeler deux initialiseurs différents de la superclasse? → Non parce que seul l'un d'entre eux sera appelé. Je ne devrais pas appeler l'initialisateur désigné de ma sous-classe (initwithvithavalues ​​:) d'InitwithCoder:? → partiellement oui. InitwithCoder: s'attend à ce que vous soyez unarchive de l'objet. C'est pourquoi nous appelons [Super InitwithCoder]; En faisant cela, la vue sera initialisée. Maintenant, vous n'avez besoin que d'introduire d'autres ivars, quelque chose que je suppose que vous faites à l'intérieur de la méthode d'initialisation.



1
votes

Malheureusement, les réponses ci-dessus ne prennent pas en compte ces choses: - (NOID) AwakafterUtilisateurCoder - et le fait qu'elle est appelée après que tout soit créé par le codeur (une fois pour chaque point de vue XIB). Awakefromnib souffre du même destin, j'ai remarqué. (La raison pour laquelle j'ai trouvé cela)

Un autre problème d'initialisation est que l'initwithcoder et l'initwithframe peuvent être évités pour des vues personnalisées. Et s'ils sont appelés, le chargement paresseux (mais pas aussi important sur les vues elles-mêmes) signifie que vous «pourrait» être en mesure de modifier des valeurs. Je crois que je l'ai fait dans InitwithCoder, mais si vous initialisez ensuite les valeurs dans Awakefromnib, c'est annulé au moins une fois. P>

Je suis allé jusqu'à: P>

- (void) awakeFromNib (or didMoveToSuperView);
{
    BOOL called = NO;
    if(!called)
    {
    called = YES;
    }

}


2 commentaires

Je pense que didmovetosuperview est un très bon endroit pour le faire pour la plupart des vues - cela couvrira une instanciation manuelle et de la nib sans plusieurs méthodes init. Pas si bon si vous avez besoin de la vue pour effectuer une logique avant qu'il ne soit à l'écran, mais si vous faites cela, il y a probablement quelque chose de mal ...


Oui, c'est en fait ce que j'ai eu recours à finalement, mais même il a une faille. Quand il est supprimé et que son superview est nul, on l'appelle également. Pas bon pour réarranger, j'ai donc ajouté un test pour "si superview nil" beaucoup comme le test appelé. Faites attention à ça! Merci pour la réponse: D