Aide pour application de dessin...
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...
).
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!
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...

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!
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
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)
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!
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
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...
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
Merci encore pour ton aide!
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.
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...
J'essaie d'avancer ça et évidemment te tiens au courant de l'avancement.
Merci encore!
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 ?
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!
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"...
J'ai toujours pas trouvé la solution...
J'espère que quelqu'un peux m'aider...
Merci!
drawingIsActive = YES est une affectation
drawingIsActive == YES est une comparaison
pour le bouton;
drawingIsActive = YES
et pour le tracé;
drawingIsActive == YES
et
drawingIsActive == NO
En gros ce que voulais dire Eric:
si tu met:
Alors tu vas affecter à maVariable la valeur "YES".
Par contre si tu fais:
c'est pour savoir si oui ou non "maVariable" à pour valeur YES.
Déjà ça c'est primordial à comprendre.
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é
Tracé :
Bouton :
EDIT : merci pour l'info "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 !