Aide pour application de dessin...

yusuke2880yusuke2880 Membre
03:02 modifié dans Vos applications #1
Bonjour,

C'est mon premier poste donc je profite pour me présenter brièvement :

Je suis designer de produit et travaille en Suisse. J'ai commencer le développement sur iPad et iPhone il y a 2 semaines. J'ai acheté de nombreux livres et passé beaucoup de temps à  faire des recherches sur le net (en gros je suis une bille... :D).

Je viens de commencer le développement d'une application de dessin sur iPad.

Pour l'heure tout fonctionne comme je le souhaite mais j'ai quelques soucis que peut-être pourrez-vous m'aider à  résoudre.

Le premier problème et que j'aimerais activer la fonction de dessin uniquement lorsque l'utilisateur appuie sur un bouton. On m'a expliqué que c'était pas si simple. J'ai donc changé ma démarche en me disant que vu mon manque de connaissance je pourrais faire en sorte que mon application dessine en transparent et que lorsque l'utilisateur appuie sur le bouton ça dessine en noir (je pense que c'est probablement pas génial).

Du coup je suis un peu bloqué...

Voici les bases lorsque je dessine dans Custom.m :

- (void) drawRect: (CGRect) rect

{
if (!self.points) return;
if (self.points.count < 2) return;

//save
UIGraphicsBeginImageContext(self.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];


/*self.currentColor = [UIColor redColor];*/
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.5f);
CGContextSetStrokeColorWithColor(context, currentColor.CGColor);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetAllowsAntialiasing(context, true);

for (int i = 0; i < (self.points.count - 1); i++)
{
CGPoint pt1 = POINT(i);
CGPoint pt2 = POINT(i+1);
CGContextMoveToPoint(context, pt1.x-60, pt1.y-50);
CGContextAddLineToPoint(context, pt2.x-60, pt2.y-50);
CGContextStrokePath(context);
}

//save
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}


et mon bouton dans ViewController.m :

- (IBAction)startBlackColorButton:(id)sender {

self.currentColor = [UIColor greenColor];

}

J'ai bien sûr tout déclaré ce que je vous illustre...

Merci!

Réponses

  • AliGatorAliGator Membre, Modérateur
    03:02 modifié #2
    Je pense que ta première idée n'était pas si mauvaise : rajoute une variable d'instance booléenne ([tt]BOOL drawisActive[/tt] dans ta classe et quand l'utilisateur a désactivé le dessin via ton bouton, au lieu de modifier self.currentColor, tu modifies l'état de cette variable drawIsActive de YES à  NO (et vice-versa).
    Et ensuite, dans ton code qui détecte le doigt (à  priori [tt]touchesBegan:withEvent:[/tt] et consoeurs), au lieu de rajouter des points dans ton tableau de points (ceux que tu vas dessiner ensuite dans le drawRect quoi), bah tu ne les rajoutes, ces points... que si drawIsActive est à  YES (donc que si le dessin est activé).

    Comme ça si tu as désactivé le dessin, tes mouvements de doigt n'auront aucun effet, ils seront ignorés... et quand tu réactives le dessin, ils seront pris en compte et rajouteront des points à  ton dessin. C'est pas plus compliqué que ça.


    Je suis en train de penser qu'il y a même plus simple, tu peux également jouer sur la propriété "userInteractionEnabled" de ta UIView qui reçoit les événements de touchers tactile (à  priori ta UIView dans laquelle tu fais également le dessin, j'imagine), pour la passer de YES à  NO : au final c'est aussi à  ça qu'elle sert cette propriété, elle existe déjà  autant en profiter (quand elle est à  NO, les événements [tt]touchBegan:withEvent:[/tt]... & co ne sont pas appelés, ils sont inhibés)
  • yusuke2880yusuke2880 Membre
    juin 2010 modifié #3
    Ouah! Merci pour la réponse rapide!

    Donc logiquement se serait bien de continuer avec ma première idée, ce qui me plait bien (c'était aussi le but souhaité à  la base).

    Par contre si j'ai tout bien compris tu me suggère d'annuler l'interactivité du touché?

    J'aurais peut-être du préciser que mon dessin et effectué par une image (ce n'est pas le cas évidemment mais lorsque l'utilisateur déplace le doigt sur l'écran, il y a un png au dessus du tracé). Donc si j'utilise le "userInteractionEnabled" toute activité avec les doigts est stoppée?

    Encore merci pour ton aide!
  • AliGatorAliGator Membre, Modérateur
    03:02 modifié #4
    Bah en fait j'ai peut-être mal compris comment ton application fonctionne. L'utilisateur ne dessine pas à  main levée (enfin à  doigt levé :D) sur l'écran, juste pour tracer des lignes (tracé libre) ?

    Donc du coup je susi pas sûr d'avoir bien compris le coup de ton PNG... mais si tu veux quand même que ton petit PNG se déplace quand le doigt bouge, mais juste que ça ne trace pas / dessine pas, alors en effet userInteractionEnabled" n'est pas ce qu'il te faut puisqu'aucun message concernant l'activité avec les doigts ne sera envoyée (enfin pour la UIView -- et ses subviews -- pour laquelle tu as mis userInteractionEnabled à  NO, bien sûr, les autres UIView qui sont autre part sur ton écran à  d'autres endroits continueront de recevoir les événements des doigts)

    Pour ton cas c'est donc peut-être plus adapté de le gérer toi-même avec un booléen comme je te le proposais au début de mon précédent message. Tu le mets à  YES ou NO selon si tu veux activer ou non le dessin, et tu le testes au bon endroit de ton code (je ne sais pas trop comment tu as organisé ton code et ta structure Model/View/Controller, il y a bien un endroit dans ton code où tu rajoutes justement des points à  ton tracé à  dessiner, quand ton doigt bouge, bah à  cet endroit tu ne rajoutes tes points que si ton booléen est à  YES et pas à  NO, quoi.
    En tout cas oui
  • yusuke2880yusuke2880 Membre
    03:02 modifié #5
    Ben en fait si on dessine avec le doigt  :D

    Lorsque l'utilisateur dessine, une image apparaà®t en même temps que le doigt (sous le doigt en fait). Je vous montrerais le résultat (c'est un peu le seul truc qui rend mon app différente donc je garde la surprise... :D).

    Voici la structure de mon app :

    DrawingAppDelegate.h
    DrawingAppDelegate.m

    DrawingViewController.h : où je déclare mon bouton
    DrawingViewController.m : où je déclare les actions de mon bouton

    Touch.h
    Touch.m : deux UIView pour dessiner et déplacer mon image

    En fait j'ai jamais utilisé de booléen... peux-tu m'en dire un peu plus? Comment dois-je écrire le code et où je dois l'écrire...

    Je sais j'en demande beaucoup  :D

    Merci encore pour ton aide!
  • AliGatorAliGator Membre, Modérateur
    03:02 modifié #6
    Ah ben heu là  va falloir sans doute relire les bases de la programmation Objective-C.
    Un booléen, c'est un type C comme un int ou un char ou un float ou un double, sauf qu'au lieu de contenir des nombres, bah ça peut juste contenir la valeur YES ou NO.

    Donc il faut que tu rejoutes une variable d'instance "BOOL drawingisActive;" dans la classe qui contient le code qui fait le dessin (celle qui rajoute les points quoi), et que dans ledit code qui rajoute les points, ne les rajouter que quand drawingIsActive vaut YES et pas NO (avec un "if(drawingIsActive)" quoi.


    Mais bon après j'ai l'impression qu'il faut tout de suite que tu fasses une pause et revienne sur les bases :
    - Si tu ne sais pas ce qu'est un booléen, ni une variable d'instance, ça me parait déjà  une base plus qu'incontournable pour aller plus loin
    - Mais également vu le peu que tu m'as décrit le projet, je ne suis pas sûr qu'il respecte correctement le MVC... Normalement si ton dessin est un ensemble de points (reliés entre eux par des lignes droites ou courbes ou des courbes de bézier) tu es sensé avoir un modèle, qui va contenir tes points et donc les données de ton dessin, et une Vue qui va faire le rendu de ces points.
    Donc modèle peut se contenter d'être un simple CGPathRef que tu vas construire au fur et à  mesure, et ta vue va se contenter de dessiner ton CGPathRef (à  la bonne échelle, avec la couleur de ton choix et la bonne épaisseur de trait) à  l'écran.
    Du coup le CGPathRef n'est créé qu'une fois, les points lui sont ajoutés uniquement quand tu déplaces ton doigt sur l'écran et que ça doit dessiner (donc ajouter des points à  ton dessin)... et dans la partie Vue du MVC, la partie qui fait le rendu quoi, donc dans le drawRect, tu ne fais que rendre le CGPathRef déjà  calculé et construit. Plutôt que de le reconstruire point par point comme tu fais, à  chaque drawrect et donc à  chaque rendu de ton image.


    Au final ce que tu veux faire n'est pas compliqué... si tu as respecté le MVC et les bases de la prog ObjC dès le début. Si tu as fait un truc un peu en vrac ou à  l'arrache (et en plus je connais pas trop l'archi que tu as utilisé) faut p'tet commencer par faire un truc propre et bien MVC pour prendre les bonnes habitudes dès le début d'une part mais aussi et surtout pour faciliter les évolutions comme celle-là  d'autre part.
  • yusuke2880yusuke2880 Membre
    03:02 modifié #7
    Merci pour tes explications! La grande classe!

    Normalement mon code doit être assez propre. Je me suis basé sur le livre de Erica Sadun et d'un autre encore. J'essaie justement de faire les choses dans l'orde et n'hésite pas à  tout recommencer dès que je vois l'ombre d'un problème.

    Je vais essayer d'appliquer tes conseils à  la lettre et publier le code pour que tu puisses vérifier tout ça. Mais normalement d'après ce que j'ai pu voir avec les différents exemples d'apple et certains de mes livres ça devrait pas être trop foireux...  :D

    J'essaie d'avancer ça et évidemment te tiens au courant de l'avancement.

    Merci encore!
  • Eric P.Eric P. Membre
    03:02 modifié #8
    Bonjour,

    Ton idée ne serait pas dans le style de celle qu'utilise le programme No.2 avec une image de crayon affichée à  l'écran et le dessin décalé du doigt ?
  • yusuke2880yusuke2880 Membre
    juin 2010 modifié #9
    Hello,

    Effectivement c'est dans le style, mais j'espère que se serra aussi intéressant (même si l'approche est un poil différente)... et que mes "petites astuces" rendront l'application intéressante... enfin y a encore du boulot!  :D

    EDIT : j'ai réussi avec l'instance BOOL (j'en ai presque les larmes aux yeux...) encore merci!

    EDIT 2 :

    alors voilà  où j'en suis :

    dans :

    - (void) touchesMoved:(NSSet *) touches withEvent:(UIEvent *) event

    if (drawingIsActive = YES) {

    CGPoint pt = touches anyObject] locationInView:self];<br /> [self.points addObject:[NSValue valueWithCGPoint:pt;
    [self setNeedsDisplay];
    }

    par contre je sais pas comment écrire le code pour que de base il soit sur "NO" et que lorsque je lance l'action du bouton il soit sur "YES"...
  • yusuke2880yusuke2880 Membre
    03:02 modifié #10
    Un petit UP!

    J'ai toujours pas trouvé la solution...

    J'espère que quelqu'un peux m'aider...

    Merci!
  • Eric P.Eric P. Membre
    03:02 modifié #11
    Bonjour,

    drawingIsActive = YES est une affectation
    drawingIsActive == YES est une comparaison
  • yusuke2880yusuke2880 Membre
    03:02 modifié #12
    donc si je comprends bien :

    pour le bouton;

    drawingIsActive = YES

    et pour le tracé;

    drawingIsActive == YES

    et

    drawingIsActive == NO
  • GreensourceGreensource Membre
    03:02 modifié #13
    Oulà  je pige pas trop ce que tu dis là .

    En gros ce que voulais dire Eric:
    si tu met:
    maVariable = YES;

    Alors tu vas affecter à  maVariable la valeur "YES".

    Par contre si tu fais:
    maVariable == YES

    c'est pour savoir si oui ou non "maVariable" à  pour valeur YES.

    Déjà  ça c'est primordial à  comprendre.
  • yusuke2880yusuke2880 Membre
    03:02 modifié #14
    Ok merci je comprends mieux!

    Donc dans mon cas lorsque on active le bouton ça dessine.

    - (IBAction)startBlackColorButton:(id)sender {

    (drawingIsActive = YES);
    }

    Par contre dans la classe qui effectue le dessin je dois lui dire que :

    il y a deux possibilité ->

    1. si activé sur YES, tu fais le dessin
    2. si activé NO tu fais pas le dessin

    mais fonction fonctionne bien lorsque je mets l'une des deux, par contre je ne vois pas comment déclarer pour qu'on aie le choix et surtout que ce soit sur NO par défaut (je sais pas si j'ai bien exprimé  :D)
  • AliGatorAliGator Membre, Modérateur
    03:02 modifié #15
    dans 1277380590:

    donc si je comprends bien :

    pour le bouton;

    drawingIsActive = YES

    et pour le tracé;

    drawingIsActive == YES

    et

    drawingIsActive == NO
    Oui c'est ça.
  • yusuke2880yusuke2880 Membre
    juin 2010 modifié #16
    et si ça ne fonctionne pas c'est que c'est mon bouton qui est mal déclaré...


    Tracé :

    - (void) touchesMoved:(NSSet *) touches withEvent:(UIEvent *) event<br /><br />{	<br />	UITouch *touch = [touches anyObject];<br />	CGPoint	locationOfPoint = [touch locationInView:self];<br />	CGRect frame = mainTouchImage.frame;<br />	frame.origin = CGPointMake(locationOfPoint.x-60, locationOfPoint.y-50);<br />	mainTouchImage.frame = frame;<br />	<br />	if (drawingIsActive == YES) {<br />		<br />		CGPoint pt = [[touches anyObject] locationInView:self];<br />		[self.points addObject:[NSValue valueWithCGPoint:pt]];<br />		[self setNeedsDisplay];<br />		<br />	}<br />	<br />	if (drawingIsActive == NO) {<br />		<br />		<br />		<br />	}


    Bouton :


    - (IBAction)startBlackColorButton:(id)sender {<br />	<br />	(drawingIsActive = YES);<br />	}


    EDIT : merci pour l'info "ceci est du code"
  • DrakenDraken Membre
    juillet 2010 modifié #17
    Utilises la balise Code pour mettre tes sources sur le site, c'est plus lisible.

    Ceci est du code

    C'est l'icône "#" entre le bouton avec l'image d'un tableau bleu et la petite bulle carrée.

    EDIT : De rien !





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