NSButton/NSRect bug ?

superniritosupernirito Membre
décembre 2013 modifié dans API AppKit #1

Yoosh, cela fait un petit temps que j'essaye de changer la position d'un bouton créer via IB mais ça ne fonctinne pas et donc je viens demander s'il y a un truc spécial à  faire sachant que j'arrive à  modifier les position de bouton que je fait avec du code.


​

 


Merci de votre aide :D


Mots clés:

Réponses

  • Non rien de spécial



    NSRect newFrame = NSMakeRect(0.0, 0.0, 30.0, 50.0);//la nouvelle position
    [self.myButton setFrame:newFrame];//changement de la position

    On peut vérifier que le bouton est bien connecté et que le code est bien exécuté avec un :



    NSLog(@%@", (self.myButton)?@button ne vaut pas nil:@button vaut nil);
    NSLog(@new frame ==> %@", NSStringFromRect(newFrame));

    Si le bouton vaut nil ca veut dire qu'il y a un problème de connection dans IB ou que le nib n'est jamais chargé.


     


    Si tu es expérimenté tu vas trouver ma réponse triviale mais les problèmes de connection arrivent souvent ;)


  • Bonjour,


     


    Jette un coup d'oeil à  ça:


     


  • devulderdevulder Membre
    décembre 2013 modifié #4

    c'est normal


     


    ton bouton  n'était pas connecter


     


    ci joint le zip modifié


     



  • Qué modifié? C'était mon projet, et le bouton était connecté  <_<




  • Qué modifié? C'était mon projet, et le bouton était connecté  <_<




    oops, j'ai mal vu désolé

  • yoosh et merci de vos réponses,


     


    Mais c'est bizarre car moi, ça ne fonctionne pas mais ça m'indique bien dans les logs que la frame a changée.​



    Edit: j'ai remarqué que le problème vient du fait que j'utilise des Custome View. Il y a un truc spécial avec les Custom View ?


    ​


  • ça dépend... je suppose que ta customView est la superView du bouton?


  • superniritosupernirito Membre
    décembre 2013 modifié #9

    je ne comprends pas.


  • Une NSView possède une superView, et cette hiérarchie remonte jusqu'à  la contentView de la NSWindow active (front and key window). Lorsque l'application reçoit un clic, elle le transmet aux subviews de la contentView en parcourant toute la hiérarchie jusqu'à  ce qu'elle trouve une vue qui traite le clic.


     


    La doc:


    https://developer.apple.com/library/mac/documentation/cocoa/conceptual/CocoaViewsGuide/WorkingWithAViewHierarchy/WorkingWithAViewHierarchy.html


    Regarde particulièrement : Moving and Resizing Views Programmatically


     

    Et là :


  • superniritosupernirito Membre
    décembre 2013 modifié #11

    ​En fait, je change le contentView à  chaque fois pour pouvoir changer de vue et donc je sais pas trop pourquoi ça ne fonctionne pas. Bref,je te donne un zip du projet.

    ​


    ​edit: j'ai changer le nom des boutons/View pour que se soit plus lisible


    ​http://www.fichier-zip.com/2013/12/31/test-2/


    ​


  • JE729JE729 Membre
    décembre 2013 modifié #12

    Tu peux re-dire le but recherché, tu veux que les 2 actions fassent quoi ? :S


    car en regardant le projet, je comprends pas trop


  • superniritosupernirito Membre
    décembre 2013 modifié #13

    Désoler.


    ​je voudrais que quand je clique sur le second bouton (donc après que le premier soit cliquer), le premier change de position/taille et que le contentView de la fenêtre devient la vue où se trouve le bouton1.


     


    En fait, je ne comprends pas vraiment pourquoi le premier bouton ne veut pas changer de position quand je fait réapparaitre sa vue (et en changeant ses positions) via le second bouton car si je faisais via le premier bouton et que je ne change pas le contentView de la fenêtre par celui du deuxième bouton, bha ça fonctionne.


    ​


    ​


    ​edit: Après plusieurs tests, j'ai remarqué que dés que je change le contentView (qui est la vue du premier bouton) pour mettre celle du seconde bouton, lorsque je switche de nouveau les View, le premier bouton retrouve les mêmes position/taille que quand je l'avais créé via IB.


     


    edit 2 : Après d'autre tests, j'ai arrêté de switcher les vues en utilisant setContentView mais j'ai utilisé [[_window contentView] addSubview:_maVue];​ et je comprends pas POURQUOI à  chaque fois que je switche pour remettre la vue du premier bouton, mon bouton retrouve les mêmes position/taille que quand je l'avais créé via IB.

  • berfisberfis Membre
    décembre 2013 modifié #14

    Lorsque tu remplaces la contentView par une autre, que crois-tu qu'il arrive à  la première? elle est écrasée. A chaque fois que tu fais appel à  la vue n°1, elle est rechargée depuis le nib. Et donc, ton bouton n'a pas l'air de bouger, parce qu'il s'agit à  chaque fois d'une nouvelle instance de ton bouton n°1, avec ses coordonnées d'origine.


     


    Par contre, comme tu as un outlet sur ton bouton d'origine, tu peux continuer à  lui envoyer des messages. Il se redimensionnera, mais... quelque part dans la mémoire, pas sur ta fenêtre...


     


    Si tu laisses les deux boutons sur la même vue, tu verras qu'en cliquant le bouton n°2, le n°1 se déplace, ou change de taille.


     


    Soit dit en passant, quelques remarques:


     


    1. Cette façon de faire ne correspond pas aux Human Interface Guidelines: l'utilisateur n'aime pas voir disparaà®tre le bouton qu'il vient de cliquer.


    2. Tu vas finir par tomber sur des zombies avec cette manière de faire: un objet désalloué auquel tu envoies un message et c'est le ticket pour la Quatrième dimension, genre BAD_ACCESS...


    3. Si tu veux redimensionner un bouton, n'en prends pas un de hauteur fixe, comme le "Round rect", mais plutôt un "Square".


     


    Je dirais, de manière générale, qu'il faut à  tout prix prendre de bonnes habitudes au départ, quitte à  y déroger... après quelque temps. Comme par exemple:


     


    1. Evite de mélanger ton code à  celui de Core Data (que tu n'utilises d'ailleurs pas)


    2. Evite les variables bouton1, vue2, etc. qui ne sont pas très parlantes


    3. Commente ton code pour te rappeler à  toi-même ce que tu as voulu faire


     


    Mais surtout, surtout lis la doc, et consulte celle qui est en français si l'anglais te rebute (c'est de l'anglais technique, 30% des mots viennent du français, ce n'est pas du Shakespeare tout de même).


     


    Courage et patience. Quand on entre dans ce monde de la programmation que l'on croit rendu plus facile à  notre époque, parce que n'importe qui, moi compris, peut pisser du code, on explore en fait un domaine de plus en plus complexe. Cela prend du temps.


     


    Mais quand ça marche... alors là , on exulte.


     


    Bonne année 2014 !


  • Merci de vos conseils à  tous, je vais de ce pas regarder la Human Interface Guidelines et essayer au pire des cas de tout faire sur une vue ou de tout simplement les superposées et de les cachées.


    Encore merci et bonne Année 2014 !


  • tout simplement les superposées et de les cachées.




     


    Ne te fatigue pas à  réinventer la roue ! Il existe dans IB la NSTabView.


     


    - Tu l'installes dans ta fenêtre, au premier niveau


    - Tu la déclares tabless (sans ces affreux tabs dont je me passe depuis longtemps)


    - Tu la dimensionnes pour qu'elle couvre la contentView


    - Tu sélectionnes le premier tabViewItem et tu y glisses ta custom view n° 1


    - Tu sélectionnes le deuxième tab et tu y glisses ta custom view n° 2


     


    Il ne te reste qu'à  lier l'action du bouton 1 (vue 1) à  l'IBAction:



    - (IBAction) switchToSecondView:(id)sender
    {
    [myTabView selectTabViewItemAtIndex:1];
    }


    myTabView est une @property IBOutlet de ton appDelegate sur la tabView.


    Le premier tab a l'index 0, comme les NSarray.


     


    Compare le nombre de lignes! Tu peux même utiliser la même IBAction pour les deux boutons, si dans IB tu mets le tag de ton bouton 1 à  0, et le tag de ton bouton 2 à  1, tu fais simplement:


     



    [myTabView selectTabViewItemAtIndex: [sender tag]];


     


    Tu te retrouves avec:


    - Moins de code


    - Une seule instance de tous tes objets (custom views et boutons) et donc qui fonctionnent comme tu veux


    - Une application plus facile à  gérer, à  la fois dans le code et dans l'interface, et plus sûre


     


    Ce n'est pas pour rien que notre ami AliGator prône la lecture de la doc. En fait, le gros souci avec Cocoa, ce n'est pas tant le code que de savoir dénicher la classe d'objet que les ingénieurs d'Apple ont conçu depuis longtemps pour résoudre ton problème.


     


    L'ennui, c'est qu'il existe des centaines de classes, avec des dizaines de méthodes chacune. Avant de réinventer péniblement une idée et te retrouver avec du code hasardeux, regarde s'il n'y a pas une classe qui va faire le travail demandé.


     


    Pourquoi je te dis ça ? Quand j'ai programmé sur mon premier MacPlus avec un truc qui s'appelait MacPascal, j'ai commencé à  créer par code les boutons avant de découvrir l'existence de la ToolBox et de ResEdit (les anciens savent de quoi je parle). Eh bien, à  l'époque, il m'a fallu acheter les volumes d'Inside Macintosh, de gros bouquins très lourds, sur lesquels j'ai passé bien des nuits. Et il n'existait pas de classes, mais des centaines de routines avec leurs paramètres... Une fois maà®trisée la doc, tout devenait plus facile... et plus sûr.


     


    Bonne lecture !

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