2017-02-26 2 views
2

J'ai un NSToolbarItem avec un NSButton comme vue et un NSMenuItem dans le menu principal. Les deux ont la même action, qui est envoyée au premier répondeur, pas à une cible particulière. Cette méthode est finalement implémentée dans une sous-classe de NSSplitViewController, quelque part dans la hiérarchie de vues de la vue de contenu de la fenêtre. Je veux valider les deux éléments, mais ce contrôleur à vue partagée spécifique s'occupe de la validation, car il dépend de certaines conditions locales à ce contrôleur. J'ai outrepassé validateToolbarItem(_:) et validateMenuItem(_:) dans ce contrôleur de vue partagée Pour l'élément de menu, cela fonctionne comme prévu. La méthode est appelée et la validation se produit. validateToolbarItem(_:) n'est jamais appelé, cependant.Validation NSToolbarItem dans le contrôleur correspondant

Selon le code Apple’s documentation, NSToolbar n'envoie pas validateToolbarItem(_:) aux éléments de la barre d'outils basés sur la vue. Pour tester cela, j'ai substitué l'élément de la barre d'outils avec un élément de la barre d'outils image et là, il fonctionne comme prévu. Sur cette base, j'ai rencontré plusieurs solutions, mais elles ne sont pas tout à fait ce que je veux.

  • Sous-classe NSToolbarItem et remplacer validate(). Cependant, aucune indication n'est donnée sur la façon dont je finis par appeler le validateToolbarItem(_:) du contrôleur. Sous-classe NSToolbar et remplacez validateVisibleToolbarItems(), puis envoyez les messages au premier répondeur.

  • Ici, je rencontre le problème, que je ne peux pas envoyer un message au contrôleur split-view, car il est en dehors de la chaîne répondeur de la barre d'outils. Sous-classe NSToolbar comme ci-dessus, mais implémentez validateToolbarItem(_:) dans un contrôleur situé dans la chaîne du répondeur, tel que NSWindowController. Cela fonctionnerait, mais alors je dois ajouter le code supplémentaire pour manipuler ce qui n'est pas nécessaire pour l'article de menu.

Existe-t-il une solution élégante pour cela qui fonctionne aussi bien que pour l'élément de barre d'outils image et l'élément de menu?

Répondre

2

J'ai écrit le code suivant dans ma sous-classe NSToolbarItem pour les boutons. Avec cette sous-classe toolbarItem, vous pouvez utiliser validateUserInterfaceItem() ou validateToolbarItem() pour valider les éléments de la barre d'outils qui contiennent un NSControl.

override func validate() { 

    // validate content view 
    if 
     let control = self.view as? NSControl, 
     let action = self.action, 
     let validator = NSApp.target(forAction: action, to: self.target, from: self) as AnyObject? 
    { 
     switch validator { 
     case let validator as NSUserInterfaceValidations: 
      control.isEnabled = validator.validateUserInterfaceItem(self) 
     default: 
      control.isEnabled = validator.validateToolbarItem(self) 
     } 

    } else { 
     super.validate() 
    } 
} 
+0

Fantastique, juste la solution élégante que je cherchais. Merci beaucoup! – Eitot

+0

Magnifique! Merci d'avoir partagé cela. Cela vous dérangerait-il d'expliquer deux choses: 1) pourquoi cela est-il nécessaire? Pourquoi Cocoa ne le fait-il pas déjà? et b) à quelle fréquence dois-je m'attendre à ce que cela soit appelé? Dans ma mise en œuvre rapide de votre code, il semble s'appeler très imprévisible, et plutôt souvent. –

+0

@ jeff-h 1) La vue interne d'un NSToolbarItem peut être plus qu'une NSControl. Donc Cocoa ne sait pas ce que c'est et donc comment le valider. 2) C'est une combinaison de déclencheurs d'événements et d'une minuterie. Vous pouvez voir le détail du timing de validation dans la référence: https://developer.apple.com/reference/appkit/nstoolbar/1516947-validatevisibleitems – 1024jp