Je sais que cette question a déjà été posée mais les réponses sont contradictoires et je suis confuse, alors ne m'enflammez pas.
Je souhaite avoir une UIView
sous-classe réutilisable dans mon application. Je veux décrire l'interface à l'aide d'un fichier nib.
Disons maintenant que c'est une vue d'indicateur de chargement avec un indicateur d'activité. Je voudrais sur un événement pour instancier cette vue et l'animer dans la vue d'un contrôleur de vue. Je pourrais décrire l'interface de la vue sans problème par programme, en créant les éléments par programme et en définissant leur cadre dans une méthode init, etc.
Comment puis-je faire cela en utilisant une pointe? Conserver la taille indiquée dans le générateur d'interface sans avoir à définir un cadre.
J'ai réussi à le faire comme ça, mais je suis sûr que c'est faux (c'est juste une vue avec un sélecteur):
- (id)initWithDataSource:(NSDictionary *)dataSource {
self = [super init];
if (self){
self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
self.pickerViewData = dataSource;
[self configurePickerView];
}
return self;
}
Mais j'écrase moi-même et quand je l'instancie:
FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
selectView.delegate = self;
selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);
Je dois régler manuellement le cadre plutôt que de le récupérer auprès d'IB.
EDIT: Je souhaite créer cette vue personnalisée dans un contrôleur de vue et avoir accès pour contrôler les éléments de la vue. Je ne veux pas de nouveau contrôleur de vue.
Merci
EDIT: Je ne sais pas si c'est la meilleure pratique, je suis sûr que ce n'est pas le cas, mais voici comment je l'ai fait:
FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
selectView.delegate = self;
[selectView configurePickerViewWithData:ds];
selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
selectView.alpha = 0.9;
[self.view addSubview:selectView];
[UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
selectView.alpha = 1;
} completion:^(BOOL finished) {
}];
Une pratique correcte est toujours souhaitée
Cela aurait-il dû être fait en utilisant un contrôleur de vue et init avec le nom de la nib? Dois-je avoir défini la pointe dans une méthode d'initialisation UIView dans le code? Ou ce que j'ai fait est-il correct?
initWithDataSource
? Quoi qu'il en soit, cela fonctionnera même si vous donnez au propriétaire la valeur «Nil».Réponses:
J'utilise ceci pour initialiser les vues personnalisées réutilisables que j'ai.
Notez que vous pouvez utiliser "firstObject" à la fin, c'est un peu plus propre. "firstObject" est une méthode pratique pour NSArray et NSMutableArray.
Voici un exemple typique de chargement d'un xib à utiliser comme en-tête de table. Dans votre fichier YourClass.m
Normalement, dans le
TopArea.xib
, vous cliqueriez sur le propriétaire du fichier et définissez le propriétaire du fichier sur YourClass . En fait, dans YourClass.h, vous auriez des propriétés IBOutlet. DansTopArea.xib
, vous pouvez faire glisser les contrôles vers ces prises.N'oubliez pas que dans
TopArea.xib
, vous devrez peut-être cliquer sur la vue elle - même et la faire glisser vers une prise, pour en avoir le contrôle, si nécessaire. (Un conseil très utile est que lorsque vous faites cela pour les lignes de cellules de tableau, vous devez absolument le faire - vous devez connecter la vue elle-même à la propriété appropriée dans votre code.)la source
Si vous souhaitez conserver votre
CustomView
et sesxib
indépendants deFile's Owner
, suivez ces étapesFile's Owner
champ vide.xib
fichier de votreCustomView
et définissez-laCustom Class
commeCustomView
(nom de votre classe de vue personnalisée)IBOutlet
au.h
fichier de votre vue personnalisée..xib
fichier de votre vue personnalisée, cliquez sur la vue et entrezConnection Inspector
. Vous trouverez ici tous vos IBOutlets que vous définissez dans le.h
fichierdans le
.m
fichier de votreCustomView
classe, remplacez leinit
méthode comme suitMaintenant, lorsque vous souhaitez charger votre
CustomView
, utilisez la ligne de code suivante[[CustomView alloc] init];
la source
-init
. Au lieu de cela, il appellerainitWithFrame:
et-awakeFromNib
. Si vous écrivez le même code pour charger votre vue que dans la-init
méthode, vous entrerez dans une boucle infinie.Suivez les étapes suivantes
UIView
.MyView.xib
.UIViewController
fromNSObject
in xib. Voir l'image ci-dessousConnectez la vue du propriétaire de fichier à votre vue. Voir l'image ci-dessous
Changez la classe de votre vue en
MyView
. Identique à 3.Voici le code pour charger la vue:
J'espère que ça aide.
Clarification :
UIViewController
sert à charger votre xib et la vue queUIViewController
possède est en fait celleMyView
que vous avez assignée dans MyView xib.Démo J'ai fait une démo ici
la source
Répondre à ma propre question environ 2 ans ou quelque chose plus tard ici mais ...
Il utilise une extension de protocole afin que vous puissiez le faire sans aucun code supplémentaire pour toutes les classes.
la source
Dans Swift:
Par exemple, le nom de votre classe personnalisée est
InfoView
Au début, vous créez des fichiers
InfoView.xib
etInfoView.swift
comme ceci:Définissez ensuite
File's Owner
àUIViewController
aimer ceci:Renommez votre
View
enInfoView
:Cliquez avec le bouton droit sur
File's Owner
et connectez votreview
champ à votreInfoView
:Assurez-vous que le nom de la classe est
InfoView
:Et après cela, vous pouvez ajouter l'action au bouton dans votre classe personnalisée sans aucun problème:
Et l'utilisation de cette classe personnalisée dans votre
MainViewController
:la source
Eh bien, vous pouvez soit initialiser le xib en utilisant un contrôleur de vue et utiliser viewController.view. ou faites-le comme vous l'avez fait. Créer uniquement une
UIView
sous - classe comme contrôleur pourUIView
est une mauvaise idée.Si vous ne disposez d'aucune prise dans votre vue personnalisée, vous pouvez directement utiliser une
UIViewController
classe pour l'initialiser.Mise à jour: dans votre cas:
Sinon, vous devez faire une personnalisation
UIViewController
(pour en faire le propriétaire du fichier afin que les prises soient correctement câblées).Où que vous souhaitiez ajouter la vue que vous pouvez utiliser.
Cependant, passer un autre contrôleur de vue (déjà utilisé pour une autre vue) en tant que propriétaire lors du chargement du xib n'est pas une bonne idée car la propriété de vue du contrôleur sera modifiée et lorsque vous souhaitez accéder à la vue d'origine, vous ne le ferez pas. y faire référence.
EDIT: Vous rencontrerez ce problème si vous avez configuré votre nouveau xib avec le propriétaire du fichier comme le même principal
UIViewController
classe et lié la propriété view à la nouvelle vue xib.c'est à dire;
Le code ci-dessous causera de la confusion plus tard, si vous l'écrivez à l'intérieur de la vue a été chargée
YourMainViewController
. En effet, àself.view
partir de ce moment, se référera à votre vue personnaliséela source