web-dev-qa-db-fra.com

Comment afficher un nouveau contrôleur de vue dans la même fenêtre Mac?

Je suis assez nouveau dans le développement Mac et la nouvelle fonctionnalité "Scénarimage" de Xcode 6 me laisse un peu perplexe. Ce que j'essaie de faire, c'est de passer d'un contrôleur de vue à un autre dans la même fenêtre. À l'heure actuelle, tous les différents NSViewControllerSegues présentent le contrôleur de vue dans une nouvelle fenêtre, qu'il s'agisse d'une modale ou simplement d'une autre fenêtre. Ce que je voudrais faire, c’est juste de passer de la même fenêtre à la même fenêtre, comme sur un iOS (bien qu’une transition animée ne soit pas cruciale). Comment cela serait-il réalisé?

16
aaplmath

Si vous fournissez une séquence personnalisée (sous-classe de NSStoryboardSegue), vous pouvez obtenir le résultat recherché. Il y a quelques pièges avec cette approche cependant:

  • la séquence personnalisée utilisera presentViewController:animator et vous devrez donc fournir un objet animateur
  • étant donné que la vue présentée n'est pas protégée par un objet Window séparé, vous devrez peut-être lui fournir une NSView personnalisée uniquement pour capturer les événements de souris que vous ne souhaitez pas propager à la vue NSViewController sous-jacente.
  • il existe également un petit problème spécifique à Swift concernant la propriété identifier du segment personnalisé que vous devez surveiller.

Comme il semble ne pas y avoir beaucoup de documentation à ce sujet, j'ai réalisé un petit projet de démonstration avec des exemples de séquence personnalisés dans Swift et Objective-C.

enter image description here

J'ai également fourni quelques détails supplémentaires en réponse à cette question .

32
foundry

(Réactiver cela au fur et à mesure qu'il apparaissait comme le premier résultat pertinent sur Google et que je rencontrais le même problème mais que je décidais de ne pas passer à la ligue)

Si les sections personnalisées fonctionnent (du moins, le code indiqué dans la réponse de la fonderie fonctionnait sous Swift 3; il doit être mis à jour pour Swift 4), le travail considérable nécessaire pour écrire un animateur personnalisé me suggère que leur principal cas d'utilisation est l'animation personnalisée.

La solution simple pour changer le contenu d'une fenêtre consiste à créer un NSWindowController pour votre fenêtre et à définir son contentViewController sur le viewController souhaité. Ceci est particulièrement utile si vous suivez le modèle typique de story-boards et instanciez une nouvelle instance de ViewController à chaque fois que vous passez. 

Toutefois.

La documentation NSStoryboard dit, très clairement dans macOS, le confinement (plutôt que la transition) est la notion la plus courante pour les storyboards , ce qui m'a amené à réexaminer les outils disponibles. 

Vous pouvez utiliser une vue conteneur pour cette tâche, qui ajoute une couche NWViewController à la place du NSWindowController décrit ci-dessus. La solution que j'ai choisie consiste à utiliser un NSTabViewController. Dans l'inspecteur d'attributs, définissez le style sur 'non spécifié'  TabViewController settings , puis sélectionnez TabView et définissez its style sur 'tabless'.  TabView selection  TabView Settings

Pour modifier les onglets par programme, définissez la selectedTabViewItemIndexde votre TabViewController.

Cette solution réutilise la même instance de ViewControllers pour le contenu de l'onglet, de sorte que toutes les données entrées dans les champs de texte sont conservées lorsque l'utilisateur bascule sur l'autre 'onglet'. 

5
green_knight

Une manière simple, sans étapes, de remplacer le contrôleur de vue actuel dans la même fenêtre:

if let myViewController = self.storyboard?.instantiateController(withIdentifier: "MyViewController") as? MyViewController {
    self.view.window?.contentViewController = myViewController
}
1
Mark