Accès classe et modification de variables

CeetixCeetix Membre
11:28 modifié dans API UIKit #1
Bonjour .

J'ai commencé à  faire du "dessin" sur l'iPhone et j'ai un petit souci qui se présente.
J'ai créer un nouveau projet de type 'Window base application'. Je créé une nouvelle classe : maVue.
En voici le code.

.h
<br />@interface maVue : UIView {<br />	NSInteger x;<br />	NSInteger y;<br /><br />}<br />@property(nonatomic,assign) NSInteger x;<br />@property(nonatomic,assign) NSInteger y;<br />@end<br />


.m
<br />@implementation maVue<br />@synthesize x,y;<br /><br />- (void)drawRect:(CGRect)rect {<br />	CGContextRef context = UIGraphicsGetCurrentContext();<br />	CGContextSetRGBFillColor(context, 100, 55, 169, 1);<br />	CGContextFillEllipseInRect(context, CGRectMake(x, y, 36, 36));<br /><br />}<br />



puis dans mon Controller j'aimerai choisir mes x,y et les transmettre à  ma classe maVue .
Voici le code de mon Controller :

<br />- (void)viewDidLoad {<br />&nbsp; &nbsp; [super viewDidLoad];<br />	maVue *cont = [[maVue alloc] init];<br />	cont.x = 80;<br />	cont.y =60;<br />}<br />


Problème, mon cercle se dessine très bien mais apparait aux coordonnées (0,0) alors que je lui ai dit de se mettre en (200,200) .
Pourquoi ça ne marche pas?
Je pense que c'est une erreur stupide mais je comprends pas ...
Merci .
«1

Réponses

  • schlumschlum Membre
    mars 2009 modifié #2
    Toutes les fonctions graphiques travaillent avec des flottants... toi avec des integers...
    Normalement il y a cast automatique, mais c'est pas optimisé et ça peut être un vecteur de bugs.
  • schlumschlum Membre
    11:28 modifié #3
    Par ailleurs, pour une UIView, c'est pas "- (id)initWithFrame:(NSRect)frameRect" ? (comme NSView...)
  • schlumschlum Membre
    11:28 modifié #4
    Et pour situer le contexte (jamais fait d'iPhone SDK), "- (void)viewDidLoad" c'est appelé quand et par qui ? C'est ici qu'il faut allouer les éléments UI ?
  • CeetixCeetix Membre
    11:28 modifié #5
    Bon j'essaie de dessiner un rectangle avec mon iniwithframe mais ça ne fait rien du tout .
    Voici ma fonction :

    <br />(id)initWithFrame:(CGRect)frame {<br />&nbsp; &nbsp;  if(self = [super initWithFrame:frame]) {<br />&nbsp; &nbsp; &nbsp;  frame = CGRectMake(10,10,50,200);<br />&nbsp; &nbsp; &nbsp;  [[UIColor blackColor]set];<br />&nbsp; &nbsp; &nbsp;  UIRectFill(frame);<br />&nbsp; &nbsp;  }<br />&nbsp; &nbsp;  return self;<br />}<br />
    
  • schlumschlum Membre
    11:28 modifié #6
    Vu que t'appelles "init" au lieu de "initWithFrame", c'est un peu normal à  vrai dire...
  • Philippe49Philippe49 Membre
    11:28 modifié #7
    dans 1236084809:

    Bon j'essaie de dessiner un rectangle avec mon iniwithframe mais ça ne fait rien du tout .

    Cela ne peut pas marcher
    1) parce que les dessins se font dans   -(void) drawRect:(CGRect) rect (sauf exception qui nécessite d'utiliser un CGContext
    2) parce qu'il y a de fortes chances que cette méthode ne soit pas appelée , enfin cela dépend de ta manière de charger le système viewcontroller/view. Pour préciser, si la vue est dans un xib, initWithFrame n'est pas appelée.

    Dans la méthode générale de chargement via un xib personnalisé, c'est viewDidLoad qui est appelée pour compléter l'initialisation, ou loadView si aucune vue n'est définie pour le contrôleur, et dans ce dernier cas, il faut tout faire par code :
    /*
    // Implement loadView to create a view hierarchy programmatically, without using a nib.
    - (void)loadView {
    }
    */


    /*
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    */


  • Philippe49Philippe49 Membre
    11:28 modifié #8
    De plus ta vue est créée par maVue *cont = [[maVue alloc] init]; (comme le dit Schlum, il faut faire [[maVue alloc] initWithFrame:frame]; ) et elle devrait être ajoutée à  la vue du viewController par addSubview
  • CeetixCeetix Membre
    11:28 modifié #9
    ok je reviens au début comme j'était sauf que j'initWithFrame avec frame.
    Mais il ne connait pas frame :s
  • schlumschlum Membre
    11:28 modifié #10
    dans 1236087376:

    ok je reviens au début comme j'était sauf que j'initWithFrame avec frame.
    Mais il ne connait pas frame :s


    Une petite recherche Google me donne des codes du genre :

    UIView *mview = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    


    C'est pas ça que tu cherches ?
  • CeetixCeetix Membre
    11:28 modifié #11
    Eu là  j'avoue etre perdu.
    Si je mets ta ligne de code je ne peux plus acceder aux variables de ma classes "maVue".
  • schlumschlum Membre
    11:28 modifié #12
    Ben, c'est ton même code que le premier message...  ???

    - (void)viewDidLoad {<br />&nbsp; &nbsp; [super viewDidLoad];<br />	maVue *cont = [[maVue alloc] init];<br />	cont.x = 80;<br />	cont.y =60;<br />}[/code]<br /><br />-&gt;<br /><br />[code]- (void)viewDidLoad {<br />&nbsp; &nbsp; [super viewDidLoad];<br />	maVue *cont = [[maVue alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];<br />	cont.x = 80;<br />	cont.y =60;<br />}
    

  • CeetixCeetix Membre
    11:28 modifié #13
    oui j'ai fait ça et c'est tjs pareil. Quand je fais un NSLog dans "maVue" et donc dans ma fonction DrawRect x et y sont à  0.
  • schlumschlum Membre
    11:28 modifié #14
    Faut peut-être demander un "setNeedsDisplay" après avoir changé x et y non ?
  • CeetixCeetix Membre
    11:28 modifié #15
    Ca sert a quoi ? Car dans la doc Apple j'ai du mal à  comprendre
  • schlumschlum Membre
    11:28 modifié #16
    dans 1236093560:

    Ca sert a quoi ? Car dans la doc Apple j'ai du mal à  comprendre


    À demander à  la vue de se re-dessiner (complètement ou en partie)
  • CeetixCeetix Membre
    11:28 modifié #17
    Hum ok.
    Bah j'ai essayer de mettre
    [maVue setNeedsDisplay:YES];

    dans viewdidload mais là  plus rien ne charge.
  • Philippe49Philippe49 Membre
    11:28 modifié #18
    Avec UIView [maVUe setNeedsDisplay] sans YES.
  • CeetixCeetix Membre
    11:28 modifié #19
    C'est ce que j'ai fait après mais il me met en warning :

    "maVue may not respond to +setNeedsDisplay"

  • Philippe49Philippe49 Membre
    11:28 modifié #20
    C'est ton instance (cont) et non la classe maVue qui doit recevoir le message setNeedsDisplay  :  [cont setNeedsDisplay]
  • CeetixCeetix Membre
    11:28 modifié #21
    Ah d'accord.
    Bon ca compile très bien et tout se charge correctement mais mon cercle reste toujours en (0,0) .  :(
  • Philippe49Philippe49 Membre
    11:28 modifié #22
    dans 1236103396:

    Ah d'accord.
    Bon ca compile très bien et tout se charge correctement mais mon cercle reste toujours en (0,0) .  :(

    Là  sans avoir plus d'information sur ton code, c'est difficile
    En relisant ce qui précède, il me semble que tu espères un repositionnement avec :
    cont.x = 80; 
    cont.y =60;

    Si c'est cela,
    1) Les properties x devraient être en CGFloat parce que c'est comme cela que ça se fait dans les kits Apple, et donc plutôt
    cont.x = 80.0; 
    cont.y =60.0;
    2) au minimum, un setNeedsDisplay après le changement de ces valeurs. Personnellement, je ferais un setter personnalisé dans le code de MaVue:
    -(void) setX:(CGFloat) CGFloat anX {
    x=anX;
    [self setNeedsDisplay];
    }
    idem en setY

    Je mettrais un NSLog("%.2f",x); dans ces setter pour voir si tout marche bien.
    Et si le cercle s'obstine à  rester en (0,0) je regarederais le code dans la méthode drawRect pour voir si d'aventure il n'y a pas là  quelqu'erreur ...
  • CeetixCeetix Membre
    mars 2009 modifié #23
    Pour le point 1) je l'ai fait dès qu'on m'a dit que ce n'était pas des entiers. J'ai donc vite pensé à  CGFLoat .
    Je vais essayer le point 2.
    Par contre une fois ta fonction setX ecrite. Tu l'appelles où ?

    ps: tu n'aurai pas mis CGFloat en double dans le prototype de ta fonction ^^
  • schlumschlum Membre
    11:28 modifié #24
    Attention, CIVector n'a-t-il pas de "setX:" ? Non... ouf, c'est bon  ;D
  • CeetixCeetix Membre
    11:28 modifié #25
    Je passe en mode arrachage de cheveux :(
  • schlumschlum Membre
    mars 2009 modifié #26
    Moi je me demande si la vue que tu alloues est celle qui est utilisée pour dessiner... Tu n'en as pas mis une dans IB par hasard ?

    ça m'étonne cette vue allouée au milieu de nulle part et affectée à  rien comme ça.
    Enfin faut que tu revoies un peu le système d'allocations des vues et objets d'interface je crois  :P
  • schlumschlum Membre
    11:28 modifié #27
    Atta, rassure moi...

    - (void)viewDidLoad {<br />&nbsp; &nbsp; [super viewDidLoad];<br />	maVue *cont = [[maVue alloc] init];<br />	cont.x = 80;<br />	cont.y =60;<br />}
    


    ça, c'est pas une méthode de "maVue" quand même ?!

    Si oui, je crois que tu mélanges un peu tout...
    Essaie ça, ça devrait aller mieux :

    - (void)viewDidLoad {<br />	[super viewDidLoad];<br />	x = 80;<br />	y =60;<br />	[self setNeedsDisplay:YES];<br />}
    

  • CeetixCeetix Membre
    11:28 modifié #28
    Eu non c'est une méthode de mon Controller.
    Meme si pour vérifier je prends ton code ça marche pas.
    Enfin je pense pas m'être trompé sur ça.. enfin j'espère.

    Si quelqu'un veut mon projet pour jeter un coup d'oeil ...

  • Philippe49Philippe49 Membre
    11:28 modifié #29

    Et il y a effectivement une maVue dans le xib + une créée dans viewDidLoad. Il faut choisir entre un procédé ou l'autre, mais pas faire les deux.

    Le plus simple serait de supprimer de supprimer le code d'initialisation dans viewDidLoad, de crééer un IBOutlet et de le connecter dans IB.
    Enfin dans la méthode -(void)viewDidAppear paramétrer ton dessin
    -(void)viewDidAppear :(BOOL) animated{
    cont.x = 80.0;
    cont.y = 60.0;
    [cont setNeedsDisplay];
    }

    ps : en supprimant le Build des dossiers compressés, on réduit considérablement la taille des fichiers transmis, merci


  • CeetixCeetix Membre
    11:28 modifié #30
    Ah ok je ne savais pas sorry.
    Merci beaucoup philippe.
    Comme ca je peux dragger mon cercle avec touchesMoved cest cool.
    Dsl pour les build  ::)
  • schlumschlum Membre
    11:28 modifié #31
    Donc il y avait bien une vue dans IB comme je le supposais  :P

    Ce qui m'a fait tiquer, c'est que dans ce code, la vue allouée ne pouvait être utilisée par personne ! (c'est d'ailleurs un pur leak...)

    - (void)viewDidLoad {<br />&nbsp; &nbsp; [super viewDidLoad];<br />	maVue *cont = [[maVue alloc] init];<br />	cont.x = 80;<br />	cont.y =60;<br />}
    
Connectez-vous ou Inscrivez-vous pour répondre.