[Résolu] Créer un fichier d'aide...
Alf1996
Membre
Bonsoir,
J'ai parcouru la doc un peu dans tous les sens, les guides, les références... et je n'ai rien trouvé sur le sujet. Quelle est la bonne méthode pour développer une aide pour une application ? J'avais pensé à une page web, mais je souhaiterais que l'aide soit accessible même si l'on n'a pas de réseau.
Une petite piste ? Sachant qu'en plus j'ai prévu d'avoir une solution localisable (anglais/français)...
Merci d'avance
J'ai parcouru la doc un peu dans tous les sens, les guides, les références... et je n'ai rien trouvé sur le sujet. Quelle est la bonne méthode pour développer une aide pour une application ? J'avais pensé à une page web, mais je souhaiterais que l'aide soit accessible même si l'on n'a pas de réseau.
Une petite piste ? Sachant qu'en plus j'ai prévu d'avoir une solution localisable (anglais/français)...
Merci d'avance
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En fait une application iOS est sensée être pensée pour pouvoir être utilisée de façon naturelle et donc ne pas forcément nécessiter de gros guide utilisateur. Mais bien sûr, selon les applications, il est quand même utile parfois d'avoir un peu de doc.
Selon ton cas et besoin tu peux donc prévoir un peu ce que tu veux, tu as le choix :
Dans tous les cas tu pourras toujours, lorsque tu vas créer le contenu de ton aide, mettre ce contenu dans des dossiers localisés (.lproj) pour que ce soit le bon contenu en fonction de la langue qui soit sélectionné. En effet on peut localiser toutes les ressources dans une application iOS. Y'a pas que les fichiers .strings qui vont dans les dossiers "en.lproj" et "fr.lproj" & co, on peut aussi mettre des images, des plist, des html, ou tout ce que tu veux et ça suivra le même principe (à savoir iOS ira chercher le fichier dans le bon dossier .lproj selon la langue de l'utilisateur).
J'aime bien la solution un peu comme dans Fling donc je parle plus haut pour des instructions ou un aide sur l'utilisation de ton appli en quelques étapes simples, ça permet de se plonger dans une application rapidement sans avoir à lire un gros pavé, juste avec quelques captures ou animations.
Fling combine dans ses écrans d'instructions à la fois du texte (genre "pour pousser une balle, faites glisser votre doigt blablabla"), et une petite animation (capture d'un plateau de jeu avec des balles, et animation d'une image de doigt qui vient pousser la balle pour te montrer comment faire), ce qui n'est pas forcément simple à faire (faut avoir des talents de dessinateur, et prévoir que ton aide soit animée, bref c'est pas juste un fichier HTML quoi) faut prendre un peu de temps pour rédiger ton aide.
Mais tu n'es pas obligée d'aller aussi loin. Tu peux juste faire des écrans contenant chacun une image et un texte en dessous, l'image correspondra sans doute à une capture de ton application, annotée avec quelques flèches, le texte expliquera le but de cet écran et des boutons, tu présentes tout ça avec un UIPageViewController, et autant pour les captures tu peux ne les avoir qu'une fois pour toutes les langues, autant pour le texte tu peux prévoir par exemple un plist pour décrire la liste des tes écrans d'aide (avec le nom de l'image à utiliser) et leur texte associé, plist qui sera lui localisé...
Enfin bref, ce ne sont que des pistes, ça dépend vraiment ce que tu veux comme type d'aide. Bien sûr il reste le gros fichier HTML, présenté dans une UIWebView, mais ça fait un peu trop "pompeux" et trop "gros guide utilisateur que personne ne lit" pour une application iOS et l'idée de simplicité que ça doit dégager je trouve pas ça forcément adapté, personnellement.
Tout à fait d'accord... Dans mon cas, j'ai un ou deux boutons dont l'utilité est un peu moins évidente et c'est pour préciser à quoi il sert que je souhaite faire une aide, mais entre nous, si on clique dessus, on trouve assez vite à quoi il servent !
Je vois ce dont il s'agit, mais je n'arrive pas à lire le lien... Il me renvoie une erreur !
J'ai vu çà effectivement dans un post où tu avais participé, et j'ai fait un essai avec un fichier pdf que j'ouvrais dans une UIWebView. Malheureusement, çà m'a donné quelque chose de pas très joli, et c'est pourquoi j'ai posé ma question...
Par contre le principe de la localisation avait bien fonctionné. /thumbsup.gif' class='bbc_emoticon' alt='' />
Tout à fait d'accord, il faut un truc bref, sinon les utilisateurs ne le lisent pas ! Et après, ils râlent... C'est bien connu, quand on est "utilisateur", on est des gros fainéants !!! /tomato.gif' class='bbc_emoticon' alt=' ' />
En tout cas, merci infiniment de ton aide. Quel post fleuve... et comme toujours plein de bonnes informations ! /implore.gif' class='bbc_emoticon' alt=' ' />
Salut,
Dans mon app j'ai mis une aide ... ou plutôt une explication des différentes fonctions
et d'autres infos ... Calculs.
J'ai utilisé une UIWebView avec un fichier html pour chaque langue.
A+,
Gil.
Je vais étudier toutes les solutions...
Pour le lien, autant pour moi, c'était dans une discussion privée donc normal que tu n'arrives pas à lire le lien que j'ai mis plus haut /wink.png' class='bbc_emoticon' alt=';)' /> Voilà la capture que j'avais bidouillé pour expliquer à Céroce :
La dernière solution est peut-être la plus simple à mettre en oeuvre : ça te laisse de la place sur chaque écran d'aide pour expliquer un bouton à la fois (ou maximum 2, peut-être), sans risquer d'avoir un écran d'aide trop chargé, et ça peut se faire par code avec un PLIST qui décrit tes textes à mettre dans un UILabel que tu mets en plein milieu de chaque écran d'aide (puisqu'il n'y aura alors qu'un texte par écran).
Et pour les flèches :
A mon avis la meilleure solution est donc la première (aucune capture à embarquer dans ton bundle, afficher la vue d'aide en surimpression de l'écran correspondant quand ledit écran est affiché pour la première fois par l'utilisateur, et placer les flèches et le texte par code)
Décidément, j'ai pas de chance avec tes liens aujourd'hui... Celui-ci non plus ne fonctionne pas !
C'est effectivement ce que j'avais envisagé... J'aime bien l'idée de la vue semi transparente noire que j'ai déjà vu dans certaines applications, mais cela ne sera pas adapté à tout... D'où le "mix".
M'en vais de ce pas étudier UIBezierPath que je n'ai jamais utilisé !
Merci pour tout !
/grin.gif' class='bbc_emoticon' alt=';D' /> /grin.gif' class='bbc_emoticon' alt=';D' /> /grin.gif' class='bbc_emoticon' alt=';D' /> /grin.gif' class='bbc_emoticon' alt=';D' />
Ma réflexion m'amène au fait qu'il va me falloir 3 vues différentes, et je pensait les faire changer avec un UIPageControl (que je n'ai pas encore utilisé, mais je devrais m'en sortir avec la doc...).
Là ou çà coince, c'est sur la définition des pages en question. En fait, il faut que je trace le tout par code, ou puis-je m'appuyer sur un fichier nib qui comporte le fond ? Quelle est la meilleure façon de procéder ?
Merci d'avance
Mais la nuit m'a porté conseil... J'ai donc trouvé une solution en créant ma view par code. Je n'ai pas totalement terminé, mais je reviendrai poster ma solution quand ce sera finalisé, demain probablement car je ne vais pas y travailler beaucoup aujourd'hui. /kiss.gif' class='bbc_emoticon' alt=':-*' />
J'ai réussi à créer une vue semi transparente avec une scrollView, associée à un UIPageControl, et çà fonctionne ( /cliccool.gif' class='bbc_emoticon' alt=' ' /> ), sauf que pour l'instant, sur la vue je ne sais mettre que des UILabel. /baby.gif' class='bbc_emoticon' alt=' ' />
Maintenant, je tourne en rond pour essayer de dessiner des flèches sur cette vue. J'ai donc étudié UIBezierPath et la doc Apple.
Je n'arrive pas à comprendre à quoi correspond les "context". Lorsque j'utilise UIBezierPath, je ne vois pas comment je dois indiquer que le tracé que je suis en train de dessiner doit se faire sur telle ou telle UIView.
Avec ce code (exemple de flèche "bidon" pour comprendre le principe):
J'ai une erreur sur le "stroke" :
Mes recherches sur les contexts ne m'ont pas permis de comprendre...
Bon peut-être que la nuit me portera conseil, mais si vous avez une piste, je serais comblée ! /implore.gif' class='bbc_emoticon' alt=' ' />
Quand tu demandes de dessiner un trait, par exemple de faire [pathArrow stroke] pour demander un "tracé d'un UIBezierPath sur le contexte courant", ce path va être tracé non seulement sur le contexte actuel (par exemple l'écran, ou une image bitmap offscreen, ou autre, selon quand tu appelles ce code) mais avec la couleur de tracé "courante" et l'épaisseur de trait "courante", couleurs et épaisseur qui ne sont pas rattachées à un UIBezierPath mais bien au contexte qui garde l'état "courant".
C'est un peu en quelques sorte ce qui dit quel crayon tu utilises (le crayon rouge à pointe fine, le feutre bleu à pointe épaisse ?) et où est ce crayon sur la page (car ensuite tu peux demander de tracer un trait "de la position courante jusqu'à tel point", et là encore c'est le contexte qui se souvient de "la position courante de ton stylo"). Donc si tu veux tracer ta flèche en rouge, c'est au contexte qu'il faut demander de passer la couleur de trait en rouge (changer de crayon), avant de tracer ton path sur ce contexte.
Les contextes sont fournis :
- Soit par le runtime, quand il passe dans la méthode "-drawRect:" d'une UIView. Dans ce cas quand le Runtime en est à la phase où il dessine les UIViews à l'écran, il crée un contexte, correspond au contexte de "rendu sur l'écran", avant d'appeler le drawRect de chaque UIView. Et du coup tous tes appels de méthodes de dessin que tu exécutes dans drawRect vont alors se dessiner sur ce contexte, autrement dit directement à l'écran.
- Tu peux aussi créer un contexte bitmap toi-même, par exemple pour dessiner "OffScreen". Le cas d'usage le plus typique étant de créer un contexte avec UIGraphicsBeginImageContext(size) qui va préparer un contexte graphique correspondant à une "image bitmap", puis tu appelles tes méthodes de dessin comme [pathArrow stroke] ou autres, ce qui va dessiner ton path "sur ce contexte bitmap" (donc en mémoire, et pas à l'écran). Et quand tu as fini de tout dessiner, tu peux appeler UIGraphicsGetImageFromCurrentImageContext qui va te renvoyer une UIImage représentant ce que tu as dessiné sur ce contexte. C'est comme ça qu'on "fait du dessin sur une UIImage" (par opposition à "dessiner à l'écran directement") ou qu'on génère des captures d'écran (en dessinant l'écran sur un contexte bitmap qu'on transforme en UIImage), ce qui permet ensuite de garder la UIImage de côté et par exemple la sauver sur le disque. Ne pas oublier d'appeler UIGraphicsEndImageContext à la fin pour libérer la mémoire du contexte précédemment créé et qu'il ne soit plus le "contexte courant")
Dans tous les cas, tu peux récupérer le contexte courant avec UIGraphicsGetCurrentContext() qui retourne un CGContextRef, ce qui est utile si tu as besoin de l'utiliser ensuite en paramètre d'une autre méthode travaillant avec les contextes, comme les méthodes pour changer la couleur courante de remplissage ou la couleur de trait ou l'épaisseur de trait...
Donc, si j'ai bien compris, je vais utiliser ma classe HelpView héritant de UIView, et je vais mettre mon code de tracé de flèche dans le drawRect de cette UIView. Et normalement le tour est joué ! /cliccool.gif' class='bbc_emoticon' alt=' ' />
Je vais voir çà dès ce soir...
Merci infiniment pour ces explications hyper claires /thumbsup.gif' class='bbc_emoticon' alt='' /> /clap.gif' class='bbc_emoticon' alt=' ' />
http://www.shutterstock.com/pic-86817934/stock-vector-vector-doodle-funny-arrows-set.html
C'est plutot fun comme flèches pour une doc et c'est souvent utilisé dans les pubs. Moi, j'y songe depuis pas mal de tps pour une sorte de "didactitiel" rapide pour mes applis.
Mais je ne fait qu'y songer... Et faire ça en Bezier... Aouch... Peut être avec les générateurs de code ?
/kiss.gif' class='bbc_emoticon' alt=':-*' />
idem avec des fichiers localisés. c'est nickel, très rapide à construire et à maintenir
C'est vrai que c'est sympa comme flèches... mais je vais faire "simple" dans un premier temps. Pour reprendre la métaphore de la construction de maison, je vais poser des fenêtres simple vitrage pour commencer, je passerai en double vitrage un peu plus tard !
Merci également pour ce retour... Je suis partie sur la solution de la UIScrollView semi transparente qui me plais pas mal, même si c'est un peu plus complexe pour moi c'est vrai. J'en ai profité pour apprendre à utiliser UIPageControl, UIScrollView, et maintenant UIBezierPath.
En plus je ne maitrise pas du tout le html... Et pourtant, il va falloir que je m'y mette aussi /huh.gif' class='bbc_emoticon' alt='???' />
Merci à tous pour votre aide. Je fais tourner tout çà et je mettrai un bout de code exemple pour les suivants. /clap.gif' class='bbc_emoticon' alt=' ' />
Le plus simple est effectivement le mieux.
Le plus simple, il me semble, c'est de proposer une aide contextuelle qui intègre les usages les plus courants de navigation et d'affichage.
Navigation dans l'aide de façon UINavigationControleur :
- A partir d'un icône sur l'écran principal ;
- Une view avec un menu (TableView Grouped) qui affiche les quelques contextes structurants ;
- Des cells qui appellent la View des détails contextuels.
Passage de la row courante pour que la View des détails affiche le HTML contextuel demandé
dans sa UIWebView plein écran sous la barre de navigation
le scroll est pris en charge par le WebView)
J'utilise exactement les mêmes .h .m .xib à chaque application.
A chaque fois je change que les fichiers HTML dans les ressources.
Les libellés du TableView viennent d'un Localizable.strings pour ne rien fixer en dur dans le code.
Pour les fichiers HTML, je me foule pas :
- Copier/coller du texte au kilomètre dans un BODY
- Ajout plein de </br> de fin de ligne, pour que ça tombe bien dans l'iPhone
- Création de quelques classes CSS pour homogénéisé les gras, couleurs, police, titre, ...
(ca evite d'avoir à ajouter des style= partout et améliore la lisibilité du HTML)
- Insertion de quelques hard copy écrans rognée sur un bout contextuel
J'ai donc créé une HelpView sur laquelle j'ai mis une UIScrollView et un UIPageControl. Pour le fonctionnement du scroll, je me suis inspirée de l'exemple fourni par la doc Apple, mais au lieu de mettre des ViewControllers dessus, j'y ai mis des UIViews semi transparentes.
Voici une copie d'écran du résultat (première page du tuto) :
HelpView.m :
OneArrow.h :
OneArrow.m :
dans le viewDidAppear (et pas dans le viewDidLoad) :
avec la méthode prepareHelpPage, et les méthodes utilisées pour le scroll :
Encore un grand merci à tous pour vos contributions, et surtout Ali pour ses posts fleuves (mais je crois que sur ce post là j'ai du battre ton record de longueur... )
Petite question, pourquoi avoir mis 2 float x et y dans OneArrow pour la largeur et la hauteur, alors que tu avais bien mis un CGPoint pour l'origine ? Pourquoi ne pas avoir mis un CGSize (si c'est une largeur/hauteur) ou un autre CGPoint (si c'est un point d'arrivée) du coup plutôt que x et y ? ça serait plus cohérent non ?
Sinon idée d'amélioration comme je t'avais dit sera pour tes futures pages de mettre tes données (texte + coordonnées de flèches) dans un PLIST (représentant un NSArray de NSArrray de NSDictionary, donc un NSArray de NSDictionary par page, un dictionnaire par flèche, chaque dictionnaire contenant donc le texte et les coordonnées de départ et arrivée de la flèche), plutôt que de faire un gros switch/case et de modifier ton code si tu as à rajouter des flèches et des pages. En plus ça aiderait à séparer le code (logique/algo) des données (pages, textes, coordonnées flèches), ça pourrait être un bon exercice :-P
En tout cas c'est bien parti et ça rend plutôt bien donc bravo !
Allez pour chipoter un peu, préférences personnelles, je mettrais un peu moins de transparence sur la HelpView (pour la rendre un poil plus foncée) et rajouterai une shadowOffset et shadowColor à tes UILabels pour qu'ils ressortent mieux et se distinguent un peu plus de ton écran d'application ;-)
J'avoue que je ne me suis pas posée la question... Mais dans mon cas x et y peuvent être négatifs. çà dépend d'où part ma flèche ; Si je mets un CGSize, est-ce que je peux avoir height et/ou width négatif ? Je ne trouve pas la réponse, mais apparemment c'est possible car ce sont des CGfloat... A confirmer
Oui, c'est vrai, ce serait plus lisible. Je vais le faire, çà me permettra de réduire la taille de mon fichier "Localizable.strings" qui commence à être un peu gros !
Merci ! Le compliment me touche beaucoup venant de toi !
J'avais également prévu de foncer un peu la vue, mais pour la copie d'écran j'ai pensé que c'était mieux de l'éclaircir un peu. Concernant shadowOffset et shadowColor, je ne connais pas, mais c'est le meilleur moyen de s'y mettre.
Merci encore pour tout ! /thumbsup.gif' class='bbc_emoticon' alt='' />
Mais bon en même temps je suppose que tu les as tous mangés :-P
PS : et oui les CGSize sont des CGFloat donc peuvent être négatifs ! C'est vrai que ça peut sembler bizarre conceptuelle est une largeur négative par exemple mais dans ton cas ça a du sens... c'est le cas de le dire ^^
Mais non, c'est une légende les chats mangés par Alf !!! /cool.gif' class='bbc_emoticon' alt='8--)' />
Mon Labrador qui se prénommait Alf n'en a jamais mangé... mais il en a coursé des dizaines... des centaines /angry.gif' class='bbc_emoticon' alt='>:(' /> /evil.gif' class='bbc_emoticon' alt='>:D' />
Comme ça tant qu'à faire tu auras de l'ombrage tant pour tes labels que pour tes flèches ;-)
Testé... et approuvé ! /clap.gif' class='bbc_emoticon' alt=' ' />
En ajoutant ceci au début et à la fin du drawRect :
Alors 2 questions :
=> l'as tu "peaufiner" pour la rendre plus flexible ?
=> serais tu ok pour pour que je le reprenne pour mon appli ?
Et jamais 2 sans 3 : je comprend rien à cette ligne :
for (int ii=0; ii<knumberofpages; ii++)="" {="" uiview="" *helppage="[self" preparehelpview:ii];="" [self.helpviews="" addobject:helppage];="" }="" préparation="" de="" la="" uiscrollview="" self.thescrollview="UIScrollView"[/size][/font][/color][color=#000000][font=monospace][size=3] alloc[/size][/font][/color][color=#666600][font=monospace][size=3="" initwithframe:posview];="" self.thescrollview.contentsize="CGSizeMake(self.view.frame.size.width" *="" knumberofpages,="" self.view.frame.size.height);="" self.thescrollview.pagingenabled="YES;" self.thescrollview.showshorizontalscrollindicator="NO;" self.thescrollview.showsverticalscrollindicator="NO;" self.thescrollview.scrollstotop="NO;" self.thescrollview.delegate="self;" [self="" loadscrollviewwithpage:0];="" loadscrollviewwithpage:1];="" [self.thehelpview="" addsubview:self.thescrollview];="" ajout="" du="" uipagecontrol,="" associé="" à ="" l'action="" "changepagehelp"="" self.thepagelist="[[UIPageControl" initwithframe:cgrectmake(self.view.frame.size.width="" 2-19.,="" self.view.frame.size.height-25.,="" 38,="" 30)];="" self.thepagelist.numberofpages="kNumberOfPages;" self.thepagelist.currentpage="0;" [self.thepagelist="" addtarget:self="" action:@selector(changepagehelp="" forcontrolevents:uicontroleventvaluechanged];="" addsubview:thepagelist];="" d'un="" bouton="" fermeture="" tutoriel="" uibutton="" *closebutton="[[UIButton" buttonwithtype:uibuttontyperoundedrect]="" retain];="" closebutton.frame="CGRectMake(self.view.frame.size.width-33.," 0.0,="" 33.0,="" 33.0);="" [closebutton="" settitle""="" forstate:uicontrolstatenormal];="" closebutton.backgroundcolor="[UIColor" clearcolor];="" uiimage="" *buttonimagenormal="[UIImage" imagenamed"close.png"];="" setbackgroundimage:buttonimagenormal="" setimage:buttonimagenormal="" action:@selector(closehelpview/smile.png' class='bbc_emoticon' alt=':)' />="" forcontrolevents:uicontroleventtouchupinside];="" addsubview:closebutton];="" release];="" -(uiview="" *)="" preparehelpview/sad.png' class='bbc_emoticon' alt=':(' />int)pagenum="" helpview="" *viewtoreturn="[[[HelpView" initwithframe:self.view.frame]="" autorelease];="" nsarray="" *listofarrows;="" onearrow="" *myarrow1,="" *myarrow2,="" *myarrow3,="" *myarrow4;="" uilabel="" *mylabel1,*mylabel2,*mylabel3,*mylabel4;="" calcul="" l'écart="" entre="" les="" barbuttonitems="" (4="" boutons)="" float="" deltaposbbi="(self.view.frame.size.width-44.)/3;" switch="" (pagenum)="" case="" 0:="" première="" page="" myarrow1="[[OneArrow" initwithorigin:cgpointmake(self.view.frame.size.width-17.5,="" 35.)="" width:-50="" height:60];="" myarrow2="[[OneArrow" initwithorigin:cgpointmake(22.,="" self.view.frame.size.height-40.)="" width:50="" height:-230];="" myarrow3="[[OneArrow" initwithorigin:cgpointmake(self.view.frame.size.width-22.,="" height:-150];="" myarrow4="[[OneArrow" initwithorigin:cgpointmake(22.+2*deltaposbbi,="" width:-10="" height:-60];="" listofarrows="[[NSArray" initwithobjects:myarrow1,myarrow2,myarrow3,myarrow4,nil];="" [myarrow1="" [myarrow2="" [myarrow3="" [myarrow4="" des="" labels="" mylabel1="[self" helplabel:cgrectmake(110.,="" 68.,="" 140.,="" 50.)="" :1="" :nslocalizedstring(@quitter=" ce="" tutoriel",="" @quitter=" tutoriel")="" ];="" [viewtoreturn="" addsubview:mylabel1];="" mylabel2="[self" helplabel:cgrectmake(self.view.frame.size.width-220.,="" self.view.frame.size.height-208.,="" 170.,="" :2="" :nslocalizedstring(@accéder=" au="" menu="" réglages",="" @accéder=" réglages")];="" addsubview:mylabel2];="" mylabel3="[self" helplabel:cgrectmake(self.view.frame.size.width-260.,="" self.view.frame.size.height-128.,="" :nslocalizedstring(@obtenir=" l'aide",="" @"obtenir="" l'aide")];="" addsubview:mylabel3];="" mylabel4="[self" helplabel:cgrectmake(78.,="" self.view.frame.size.height-328.,="" 220.,="" 100.)="" ="" :nslocalizedstring(@récupérer=" derniers="" sigmets",="" @mettre=" jour="" données,="" cette="" fonction="" requiers="" réseau...")];="" addsubview:mylabel4];="" break;="" 1:="" deuxième="" ...="" 2:="" troisième="" default:="" viewtoreturn.listofarrows="listOfArrows;" [listofarrows="" return="" viewtoreturn;="" -(uilabel="" helplabel:(cgrect)="" framelabel:(int)nblines:(nsstring="" *)textlabel="" *thelabel="[[[UILabel" initwithframe:framelabel]="" thelabel.numberoflines="nbLines;" thelabel.textcolor="[UIColor" whitecolor];="" thelabel.text="textLabel;" thelabel.backgroundcolor="[UIColor" thelabel;="" -="" (void)loadscrollviewwithpage:(int)page="" if="" (page="" <="" 0)="" return;="">= kNumberOfPages)
return;
WTF ?
D'ailleurs, vu que je vais travailler bientôt dessus, si vous voulez un peu d'inspiration au niveau design : Coach Marks
Pas de problème... ici on aime bien les chats...
Je n'ai rien changé pour l'instant... Je suis en plein dans les finitions de mon application (site web, préparation des copies d'écran, vérification et amélioration de la gestion des erreurs...), bref à fond ! Mais après çà peut s'envisager...
Pas de problème... On est sur un forum d'entraide, non ? Je pense avoir posté tout le code nécessaire, mais s'il manque quelque chose, n'hésite pas !
Quezako ? çà sort d'où çà ?
Edit : je viens de trouver où tu as trouvé çà ... Je vais regarder, effectivement, il y a eu un problème de copier/coller !
Je vais corriger le post en question...