2010-10-11 5 views
7

Cela semble que cela devrait être facile, mais il me manque quelque chose. J'ai une application basée sur un document. J'ai également construit un nouveau XIB qui a un NSTableView et trois boutons là-dessus que j'ai l'intention d'afficher une liste des dossiers précédents. Je souhaite que ce XIB soit affiché à la place de la fenêtre de document au premier démarrage de l'application. Une fois que l'utilisateur sélectionne un ancien fichier ou touche le bouton "Nouveau", je souhaite aller dans la fenêtre du document. C'est très commun et j'ai vu utilisé assez souvent.Démarrage d'une application basée sur un document Cocoa montre d'abord la fenêtre de sélection

Dans mes tentatives pour que cela fonctionne, j'ai modifié le fichier project-info.plist et modifié le nom de base du fichier NIB principal de MyDocument en mon nom XIB de sélection. Cela provoque l'application pour afficher la fenêtre Sélection au lieu de la fenêtre MyDocument. Il semble n'y avoir aucun problème jusqu'à présent.

Dans ma fenêtre de sélection, j'ai configuré ma vue de table et un contrôleur de tableau et un contrôleur de fenêtre personnalisé juste pour ce XIB. J'ai défini le propriétaire du fichier sur le nouveau contrôleur de fenêtre et lié la propriété window du contrôleur de fenêtre à la fenêtre et la propriété déléguée de Window au propriétaire du fichier ainsi que les boutons "Select", "Cancel" et "New". Rien n'est lié à NSApplication. Mais la chose étrange est quand je lance cette application, il semble vouloir relier ces contrôleurs à NSApplication avec l'erreur (même pour les deux autres boutons):

Impossible de se connecter le SelectButton d'action: pour cibler la classe NSApplication

Il affiche également une erreur indiquant que NSApplication n'est pas compatible avec les valeurs-clés pour la prise qui contient des références à ma baie. Le contrôleur de tableau, la fenêtre et les boutons ne sont pas liés à NSApplication mais au nouveau contrôleur de fenêtre. Je m'attendais à ce que s'il y avait un problème, ne mentionne pas NSApplication mais plutôt le contrôleur de fenêtre auquel les contrôleurs sont liés.

Quelqu'un sait ce qui se passe ici? Est-ce un problème d'action-cible parce que j'ai changé le "nom principal de base de fichier de NIB" du "menu principal" en "sélection"? Si je ne suis pas censé changer cela, alors comment puis-je obtenir Cocoa me permettre d'afficher un écran de sélection avant de montrer la fenêtre de document?

Toute aide est grandement appréciée. Rob

Répondre

9

Le paramètre dans IB pour la classe du propriétaire du fichier de la plume est uniquement consultatif; il permet à IB d'afficher uniquement les points de vente et les actions fournies par les instances de cette classe. Il n'applique pas que le propriétaire du fichier sera une instance de cette classe, car le propriétaire du fichier ne fait pas partie de la plume.

Le propriétaire du fichier est l'objet qui charge la plume. Cela signifie nécessairement qu'il est à l'extérieur de la plume, et rien dans la plume ne détermine rien à ce sujet. Dans le cas de la plume MainMenu, son propriétaire de fichier (l'objet qui charge la plume MainMenu) est l'instance NSApplication. Ainsi, tout ce que vous avez connecté au propriétaire du fichier dans votre plume MainMenu, vous vous êtes connecté à l'objet application, même si vous avez dit à IB que ce ne serait pas l'application.

Que l'application soit propriétaire de la plume MainMenu, indépendamment de ce que vous dites à IB, n'est pas le bogue. L'application est toujours le propriétaire de la plume MainMenu. C'est normal et correct. vous ne pouvez pas le changer, vous ne devriez pas essayer de le changer et vous n'avez pas besoin de le changer. Le bug, en un mot, est que vous utilisez une plume à deux fins très différentes.Vous devriez laisser la plume de MainMenu être seule - ne contenant que le MainMenu, votre contrôleur de document personnalisé (j'y reviendrai dans un instant), et votre délégué d'application - et déplacer la fenêtre de documents précédents dans un autre nib, appartenant au contrôleur de fenêtre de documents précédents. Afin d'avoir un contrôleur de fenêtre être le propriétaire de cette plume, vous devez avoir le contrôleur de fenêtre le charger. Vous devez le faire avec du code - vous ne pouvez pas le configurer dans IB ou dans un plist.

Dans le délégué de votre application, instanciez et possédez le contrôleur de fenêtre. Il semble que vous ayez créé une sous-classe NSWindowController personnalisée, vous pouvez donc remplacer son init pour qu'il envoie lui-même le message initWithWindowNibName: pour charger et posséder la pointe. Ensuite, utilisez simplement alloc et init pour créer le contrôleur de fenêtre à partir du délégué de l'application. Cela va se débarrasser du message de la console, et s'assurer que les boutons sont effectivement connectés au contrôleur de fenêtre (parce qu'ils sont connectés au propriétaire du fichier, qui, avec ce changement, sera le contrôleur de fenêtre) . Demandez à votre délégué de répondre à applicationOpenUntitledFile: en envoyant au contrôleur de fenêtre le message showWindow:. Cela fera apparaître la fenêtre des documents précédents chaque fois que l'utilisateur aurait normalement créé un nouveau document.

Si vous souhaitez prendre en charge les méthodes habituelles de création de documents (c'est-à-dire, permettre au nouveau document de fonctionner), implémentez applicationDidFinishLaunching: et applicationShouldHandleReopen:hasVisibleWindows:, et non applicationOpenUntitledFile:. Assurez-vous qu'aucun document n'est ouvert et montrez votre fenêtre si c'est le cas.

Vous devez également faire une sous-classe personnalisée de NSDocumentController et faites votre contrôleur de document une instance de cela, et dans cette classe, mettre en œuvre addDocument: et removeDocument: à reétrenner la fenêtre précédente-documents lorsque le dernier document ouvert est fermé, et cachez-le quand un document est ouvert.

+0

Cela a beaucoup aidé. Une partie de ce qui m'a découragé est que les applications de document utilisant des données de base ne créent pas automatiquement le délégué d'application. Une fois le délégué créé, j'ai pu arrêter la création automatique et ouvrir ma fenêtre initiale. Merci beaucoup! – Rob

Questions connexes