OutlineView et outlineViewItemWillExpand

Bonjour,

Voila j'ai un NSOutlineView et je voudrais récupérer des infos du NSTreeController rattaché concernant l'élément que l'on "expand"

J'ai voulu implémenter func outlineViewItemWillExpand(_ notification: Notification)
Mais je galère pour traiter notification
comme je peux récupérer des infos de l'éléments qui a été ouvert ?

Merci par avance

Réponses

  • CéroceCéroce Membre, Modérateur

    Attention, une notification n'est pas un appel de méthode. Il faut d'abord s'abonner à la notification auprès du NotificationCenter.default, en donnant le #selector sur la méthode à appeler quand cette notification est reçue.

    Ensuite, l'objet 'notification' passé en paramètre contient un champ 'object' qui correspond généralement à l'émetteur (ici l'OutlineView) et un champ 'userInfo' qui est un dictionnaire fournissant des infos supplémentaires. Tu devrais y trouver l'item. La doc d'Apple est incomplète, alors tu devras chercher le nom des clefs du dico dans NSOutlineView.h.

    Ceci dit, ce n'est pas la bonne méthode. Les notifications étant globales à l'application, ce n'est probablement ce que tu veux. Le mieux est d'implémenter le protocole NSOutlineViewDelegate. Il possède une méthode itemWillExpand.

  • yannSyannS Membre

    Bon j'ai trouvé un post objectiveC qui correspond plus ou moins à la même chose.
    J'ai transcris en swift et ça donne ça

    let node = (((notification.userInfo as! NSObject).value(forKey: "NSObject")) as! NSTreeNode).representedObject as! MonArbo

    Est ce que c'est la meilleure (ou seule) solution ?

  • yannSyannS Membre

    Ah, j'ai laissé ma précédente réponse en attente depuis hier soir, pas fait attention.
    C'est bien la méthode du protocol NSOutlineViewDelegate que j'ai implémenté
    C'est vrai que je n'ai pas été très clair entre les notifications et la notification publiée par la méthode

  • CéroceCéroce Membre, Modérateur
    22 févr. modifié #5

    Au temps pour moi. J'avais mal lu. Effectivement, la méthode du protocole fournit une notification. C'est vraiment du grand n'importe quoi; comme quoi dans le passé aussi Apple faisait du mauvais travail. J'ai toujours détesté NSOutlineView. Rien que le fait qu'elle hérite de NSTableView est une erreur monumentale.

    Bref, on trouve cela dans NSOutlineView.h:

    /* Note for the following NSOutlineViewItem*Notifications:
    The 'userInfo' dictionary in the notification will have an @NSObject key where the value is the changed (id)item.
    */
    APPKIT_EXTERN NSNotificationName NSOutlineViewItemWillExpandNotification;

    Bref, pour avoir l'item concerné, écris:

    let item = notification.userInfo[@"NSObject"] as! TypeDeLItem
    
  • Joanna CarterJoanna Carter Membre, Modérateur
    22 févr. modifié #6

    Ou, plutôt :

      guard let item = notification.userInfo[@"NSObject"] as? TypeDeLItem else
      {
        return
      }
    
      // traiter item
    

    o:)

  • CéroceCéroce Membre, Modérateur

    Non, je ne suis pas d'accord. Si l'item n'est pas du bon type, alors il s'agit d'une erreur de programmation, et il vaut mieux un plantage franc qu'une erreur silencieuse.

  • Joanna CarterJoanna Carter Membre, Modérateur

    Dans ce cas là, il faut produire une exception avant, ou à la place du return

  • yannSyannS Membre

    Je viens d'essayer

    let node = notification.userInfo!["NSObject"] as! Arbo

    ça génère une erreur
    Could not cast value of type 'NSKVONotifying_NSTreeControllerTreeNode' (0x600000101ef0) to 'test1.Arbo' (0x100018e80).
    2018-02-23 08:43:52.586057+0100 test1[1321:37684] Could not cast value of type 'NSKVONotifying_NSTreeControllerTreeNode' (0x600000101ef0) to 'test1.Arbo' (0x100018e80).

    J'ai légèrement modifier la ligne avec ce que j'avais fait précédement

    let node = (notification.userInfo!["NSObject"] as! NSTreeNode).representedObject as! Arbo

    Plus d'erreur et surtout plus légère que celle reprise d'objective C

  • CéroceCéroce Membre, Modérateur

    @Joanna Carter a dit :
    Dans ce cas là, il faut produire une exception avant, ou à la place du return

    Je ne vois pas l'intérêt, dans les deux cas, les résultats est le même: la levée d'une exception. Alors pourquoi compliquer le code ?

Connectez-vous ou Inscrivez-vous pour répondre.