2010-04-25 7 views
3

Je suis nouveau sur iPhone et objectif c. J'ai passé des heures et des heures et des heures à lire des documents et à essayer de comprendre comment les choses fonctionnent. J'ai RTFM ou au moins suis dans le processus. Mon principal problème est que je veux comprendre comment spécifier où un événement est passé et la seule façon dont j'ai pu le faire est de spécifier les délégués, mais je suis certain qu'il y a un moyen plus facile/plus rapide dans IB. .Utilisation efficace d'Interface Builder

Donc, un exemple. Disons que j'ai 20 vues différentes et voir les contrôleurs et un MyAppDelegate. Je veux être en mesure de construire tous ces différents fichiers Xib dans IB et ajouter cependant de nombreux boutons et champs de texte et autres, puis spécifier qu'ils produisent tous un événement dans l'objet MyAppDelegate. Pour ce faire, j'ai ajouté un objet MyAppDelegate dans chaque contrôleur de vue dans la vue de liste d'IB. Ensuite, j'ai créé une méthode IBAction dans MyAppDelegate dans XCode et suis retourné à IB et lié tous les événements à l'objet MyAppDelegate dans chaque fichier Xib. Cependant, lorsque j'ai essayé de l'exécuter, il s'est écrasé avec une exception de lecture incorrecte. Je suppose que chaque fichier Xib place un pointeur d'objet MyAppDelegate qui n'a rien à voir avec l'adresse MyAppDelegate qui sera créée lors de l'exécution.

Donc, ma question est ... comment puis-je faire cela?

Répondre

4

Si vous créez une instance de MyAppDelegate dans chaque fichier nib, alors, oui, vous vous retrouverez avec beaucoup d'instances différentes de la classe lorsque toutes les charges seront chargées. Le délégué de l'application n'est pas identifié par la classe ou même le protocole, mais plutôt par l'objet pointé par la propriété delegate de l'instance d'application. Pour trouver le véritable délégué de l'application, vous devez demander à l'objet application lui-même son délégué

Vous devez avoir tous vos contrôleurs de vue issus d'une classe de contrôleur de vue parent ayant une propriété appDelegate. Mettre en œuvre quelque chose comme ceci:

#import "MyAppDelegateClass.h" 

@interface ViewControllerBaseClass :UIViewController { 
    MyAppDelegateClass *appDelegate; 
} 
@property(nonatomic, retain) *appDelegate; 

@end 

@implementation ViewControllerBaseClass 
@synthesize appDelegate; 

-(MyAppDelegateClass *) appDelegate{ 
    self.appDelegate=(MyAppDelegateClass *)[[UIApplication sharedInstance] delegate]; 
    return appDelegate; 
} 
@end 

Lorsque le contrôleur de vue a besoin le délégué app appelle simplement self.appDelegate. Si vous souhaitez accéder à un attribut du délégué de l'application, utilisez self.appDelegate.attributeName. L'important est de demander à l'application son instance de délégué spécifique lors de l'exécution. Vous ne pouvez pas faire cela à partir d'un fichier nib.

+0

Si je l'ai dit @property (nonatomic, conserver) IBOutlet MyAppDelegateClass * appDelegate puis sous-classé chacun de mes viewcontrollers de cette base viewController, puis ajouter les différentes méthodes de IBAction dans mon AppDelegate se alors sûrement il y a une certaine façon de se connecter ces IBOutlets dans le constructeur d'interface au lieu de dans le code? Jusqu'à présent, je l'ai fait par programmation en plaçant simplement la propriété appDelegate à self lors du chargement des contrôleurs de vue à partir de MyAppDelegateClass mais je pense que la ligne [UIApplication ...] sera meilleure. Mais n'y a-t-il pas un moyen à IB? – twerdster

+1

Un délégué d'application est une instance spécifique. Vous devez pointer vers cette instance spécifique ou vous n'atteignez pas le délégué réel. Le simple fait de donner une classe à une classe ne laisse pas ses sous-classes pointer vers des instances spécifiques. Chacun de ces points de vente doit être lié à l'instance de délégué d'application spécifique que les objets d'application utilisent comme délégué. – TechZen

+1

Les fichiers Nib sont conçus pour être modulaires et avoir une portée restreinte. Par conception, ils ne dépendent pas et ne peuvent pas voir l'application entière ou même l'objet d'application. En tant que tel, seule la pointe détenue par l'objet application lui-même (généralement MainWindo.nib) peut voir le délégué actif. – TechZen

0

En général, vous devez créer un contrôleur de vue pour chacune des vues que vous créez et lier des événements à ces contrôleurs de vue - pas au délégué de l'application. En fait, aucun événement n'est généralement relié au délégué de l'application à partir d'un fichier nib, même dans les exemples de projets, vous remarquerez que les contrôleurs de vue sont créés et conservés par le délégué de l'application, mais ne reçoivent pas d'événements.

1

Je ne comprends pas exactement ce que vous essayez de faire, mais c'est probablement une mauvaise idée. Il ne devrait y avoir qu'un seul délégué d'application par application, et il devrait gérer le comportement de l'ensemble de l'application. En règle générale, le délégué de l'application initialise le (s) contrôleur (s) racine (s) et les affiche, mais pas grand-chose d'autre (à part gérer des éléments tels que l'ouverture et l'enregistrement des sources de données).

Les contrôleurs de vue (sous-classes de UIViewController) doivent interagir avec les XIB. Le comportement spécifique à la vue dans les contrôleurs de vue facilite considérablement la gestion et la maintenance de l'application. Typiquement, il devrait y avoir 0 ou 1 XIBs par contrôleur de vue (plus que cela est compliqué).Vous définissez l'interaction avec les vues en utilisant le modèle Cible/Action avec IBOutlets et IBActions (voir here pour un guide complet). C'est généralement une mauvaise idée de rendre les contrôleurs de vues ou les XIB dépendants du délégué de l'application (puisque la réduction des dépendances rend le code plus facile à gérer).

+0

D'accord, je vais poser une question légèrement différente alors. Comment puis-je créer un contrôleur de vue qui contrôle un certain nombre de vues différentes où chaque vue est définie dans des fichiers nib distincts. Disons que je construis 5 vues dans 5 plumes différentes avec rien d'autre dans la hiérarchie de la plume sauf les vues. Maintenant, je construis une plume avec un contrôleur de vue, mais pas de vues. Comment puis-je initialiser MyAppViewController avec une vue spécifiée au moment de l'exécution. Existe-t-il une option dans UIView pour faire cela? Dois-je alors définir le propriétaire du fichier de chaque nib-with-only-a-view comme étant de type MyAppViewController? Ou comment devrait-il être fait? – twerdster

Questions connexes