120 votes

Comment puis-je créer un custom iOS de vue de la classe et de l'instancier plusieurs copies (IB)?

Je suis actuellement en train de faire une application qui va avoir plusieurs timers, qui sont toutes identiques.

Je veux créer une classe personnalisée qui utilise tout le code pour les compteurs, ainsi que la mise en page/animations, afin que je puisse avoir 5 identiques minuteries qui fonctionnent indépendamment les uns des autres.

J'ai créé la mise en page à l'aide de l'IB (xcode 4.2) et tout le code de la minuterie est actuellement un peu dans le viewcontroller classe.

J'ai de la difficulté d'emballage de mon cerveau sur la façon d'encapsuler le tout dans une classe personnalisée, puis l'ajouter à la viewcontroller, toute aide serait grandement appréciée.

144voto

NJones Points 20265

Bien de répondre sur le plan conceptuel, votre minuterie devrait être une sous-classe de UIView au lieu de NSObject.

Pour instancier une instance de votre minuterie de l'IB faites simplement glisser un UIView déposez votre vue du contrôleur de la vue, et l'ensemble de la classe à votre minuterie du nom de la classe.

enter image description here

N'oubliez pas de #import votre classe timer dans votre vue-contrôleur.

Edit: pour la conception de l'IB (pour le code de l'instanciation de voir l'historique de la révision)

Je ne suis pas très familier avec le storyboard, mais je sais que vous pouvez construire votre interface de l'IB à l'aide d'un .xib le fichier qui est presque identique à l'aide de la table de montage séquentiel version; Vous devriez être en mesure de copier et coller votre point de vue comme un tout à partir de votre interface actuelle de l' .xib le fichier.

Pour un test, j'ai créé un nouveau vide .xib nommé "MyCustomTimerView.xib". Ensuite, j'ai ajouté un point de vue, et que l'ajout d'une étiquette et deux boutons. Comme Suit:

enter image description here

J'ai créé un nouvel objectif-C, classe de sous-classement UIView nommé "MyCustomTimer". Dans mon .xib , j'ai mis mon Propriétaire du Fichier de la classe MyCustomTimer. Maintenant, je suis libre à des actions de connexion et points de vente, tout comme tout autre point de vue/contrôleur. Le résultant .h le fichier ressemble à ceci:

@interface MyCustomTimer : UIView
@property (strong, nonatomic) IBOutlet UILabel *displayLabel;
@property (strong, nonatomic) IBOutlet UIButton *startButton;
@property (strong, nonatomic) IBOutlet UIButton *stopButton;
- (IBAction)startButtonPush:(id)sender;
- (IBAction)stopButtonPush:(id)sender;
@end

Le seul obstacle, de gauche à sauter est l'obtention de cette .xib sur mon UIView sous-classe. À l'aide d'un .xib considérablement réduit la configuration requise. Et puisque vous êtes à l'aide de story-boards pour charger les minuteries nous savons -(id)initWithCoder: est le seul initialiseur qui sera appelée. Voici donc ce que la mise en œuvre de fichier ressemble à ceci:

#import "MyCustomTimer.h"
@implementation MyCustomTimer
@synthesize displayLabel;
@synthesize startButton;
@synthesize stopButton;
-(id)initWithCoder:(NSCoder *)aDecoder{
    if ((self = [super initWithCoder:aDecoder])){
        [self addSubview:
         [[[NSBundle mainBundle] loadNibNamed:@"MyCustomTimerView" 
                                        owner:self 
                                      options:nil] objectAtIndex:0]];
    }
    return self;
}
- (IBAction)startButtonPush:(id)sender {
    self.displayLabel.backgroundColor = [UIColor greenColor];
}
- (IBAction)stopButtonPush:(id)sender {
    self.displayLabel.backgroundColor = [UIColor redColor];
}
@end

La méthode nommée loadNibNamed:owner:options: fait exactement ce qu'il sonne comme il le fait. Il charge la Plume et définit le "Propriétaire du Fichier" propriété de soi. Nous avons extrait le premier objet dans le tableau et qui est la racine de vue de la Plume. Nous ajoutons de la vue comme une sous-vue et le tour est joué c'est sur l'écran.

Évidemment, cela change juste l'étiquette de la couleur d'arrière-plan lorsque les touches sont appuyées, mais cet exemple devrait vous bien sur votre chemin.

Notes sur la base des commentaires:

Il est intéressant de noter que si vous obtenez une récursion infinie de problèmes que vous avez probablement raté le subtil truc de cette solution. Il ne fait pas ce que vous pensez qu'il est en train de faire. Le point de vue qui est mis dans le storyboard n'est pas vu, mais au lieu de charges d'un autre point de vue comme une sous-vue. Ce point de vue, il charge, c'est la vue qui est défini dans la plume. Le "propriétaire du fichier" dans la plume est l'invisible vue. La partie cool, c'est que cette invisible vue est toujours un Objectif-C classe qui peut être utilisé comme un point de vue contrôleur de toutes sortes pour le point de vue qu'il apporte de la plume. Par exemple, l' IBAction méthodes dans l' MyCustomTimer classe sont quelque chose que vous attendez plus d'un point de vue contrôleur que dans une vue.

Comme une note côté, certains pourraient faire valoir que cela rompt MVC et je suis d'accord un peu. De mon point de vue c'est plus étroitement liée à une coutume UITableViewCell, ce qui a également parfois être de la partie contrôleur.

Il est également intéressant de noter que cette réponse a été de fournir une solution spécifique; créer une plume qui peut être instancié plusieurs fois sur le même point de vue, comme posé sur une table de montage. Par exemple, vous pouvez facilement imaginer six de ces minuteurs le tout sur un écran de l'iPad à la fois. Si vous avez seulement besoin de spécifier un point de vue pour une vue contrôleur qui doit être utilisé à plusieurs reprises à travers votre application, puis de la solution fournie par jyavenard à cette question est presque certainement une meilleure solution pour vous.

39voto

jyavenard Points 974

Il y a un moyen plus facile de charger un xib à partir d'un storyboard. Dire que votre contrôleur est de MyClassController type qui en hérite UIViewController.

Vous ajoutez un UIViewController à l'aide de l'IB dans votre storyboard; modifier le type de classe à être MyClassController. La suppression de la vue qui avait été automatiquement ajouté dans la table de montage séquentiel.

Assurez-vous que le XIB vous souhaitez appelé est appelé MyClassController.xib.

Lorsque la classe sera instanciée au cours de la table de montage séquentiel de chargement, le xib sera chargé automatiquement. La raison pour cela est dû à l'implémentation par défaut de UIViewController qui appelle à la XIB nommé avec le nom de la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X