Mini Tuto iPhone : Touches, Dessin

Philippe49Philippe49 Membre
juillet 2009 modifié dans Actualités #1
Une toute chtite application iPhone pour les débutants de chez "je connais pas"

(Etape 1) On fait apparaà®tre un rectangle rouge sur l'écran.
(Etape 2) On définit une property pour le rectangle.
(Etape 3) On  touche l'écran et on écrit la position du contact.
(Etape 4) On fait glisser son doigt sur l'écran, et le rectangle rouge suit le mouvement.

Réponses

  • Philippe49Philippe49 Membre
    avril 2009 modifié #2
    Un simple rectangle rouge

    1) Créer un projet du type View-Based Application, par exemple, on va la nommer Vico.

    2) On dispose d'une classe VicoAppDelegate et d'une classe VicoViewController.

    3) Build and Go ... cela marche déjà 

    4) Ajouter une classe VicoView héritant de UIView : clic droit sur le group "Classes", et Add > New File. Choisir le template UIView.

    5) Ouvrir le xib  VicoViewController.xib par double-clic, sélectionner la vue, ouvrir le panel Identity , et mettre VicoView pour la classe de cette vue.

    6) Coder la méthode drawRect dans le fichier VicoView.m

    - (void)drawRect:(CGRect)rect {<br />	CGContextRef context=UIGraphicsGetCurrentContext();<br />	CGRect r;<br />	r.origin.x=10.;	r.origin.y=30.;<br />	r.size.width=100.;	r.size.height=130.;	<br />	CGContextSetRGBFillColor(context, 1., 0., 0., 1.);<br />	CGContextFillRect (context,r);<br />}<br />
    

    Cette méthode drawRect est appelée chaque fois que la vue doit être redessinée.

    7) Build and Go ==> un beau rectangle rouge

    Continuer :
    • Aller dans la doc de CGContextRef et utiliser d'autres formes
    • Mettre une ombre
    • Utiliser un gradient

  • Philippe49Philippe49 Membre
    avril 2009 modifié #3
    Une property
    Le but est de sortir le CGRect de la méthode de dessin drawRect pour pouvoir accéder à  ce CGRect de l'extérieur, d'en faire une variable d'instance pour pouvoir la modifier un peu de n'importe où au sein de ta UIView. Ces étapes sont nécessaires à  ce qui va suivre, permettant de modifier la position et la taille du rectangle à  dessiner.
    Le dessin de ce rectangle, lui, doit rester dans la méthode drawRect:
    (explication d'Aligator)

    8) On passe le rectangle à  dessiner en property de la VicoView

    <br />// fichier VicoView.h<br />#import &lt;UIKit/UIKit.h&gt;<br />@interface VicoView : UIView {<br />	CGRect rectToDraw;<br />}<br />@property 	CGRect rectToDraw;<br />@end
    


    <br />// Dans le fichier VicoView.m<br /><br />@implementation VicoView<br /><br />@synthesize rectToDraw;<br /><br />- (void)drawRect:(CGRect)rect {<br />	CGContextRef context=UIGraphicsGetCurrentContext();<br />//	CGRect r;<br />//	r.origin.x=10.;	r.origin.y=30.;<br />//	r.size.width=100.;	r.size.height=130.;	<br />	<br />	CGContextSetRGBFillColor(context, 1., 0., 0., 1.);<br />	CGContextFillRect (context,rectToDraw);<br />}<br /><br />- (void)dealloc {<br />    [super dealloc];<br />}<br /><br />@end<br />
    



    9) La méthode viewDidLoad est appelée après le désarchivage du xib VicoViewController.xib. Cela est l'occasion de finaliser les initialisations en définissant la taille du rectangle initial à  dessiner dans la vue.

    <br />// Dans le fichier VicoViewController.m<br /><br />#import &quot;VicoViewController.h&quot;<br />#import &quot;VicoView.h&quot;<br /><br />@implementation VicoViewController<br />// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.<br />- (void)viewDidLoad {<br />	[(VicoView*)(self.view) setRectToDraw:CGRectMake(10.,30.,100.,100.)];<br />    [super viewDidLoad];<br />}
    


    10) Build and Run



  • Philippe49Philippe49 Membre
    avril 2009 modifié #4
    Localiser un touch

    Ne pas oublier de cocher "User Interaction Enabled" sur la vue dans IB.
    (Commentaires d'Aligator)

    11) Mettre dans VicoViewController.m la méthode suivante :
    <br />- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {<br />	UITouch * touch=[touches anyObject];<br />	CGPoint touchLocation=[touch locationInView:self.view];<br />	NSLog(NSStringFromCGPoint(touchLocation));<br />}<br />
    


    12) Build and run et ouvrir la console : On doit y voir les coordonnées du point de contact, que l'on peut contrôler par rapport au rectangle rouge présent dans la vue.
  • Philippe49Philippe49 Membre
    avril 2009 modifié #5
    Suivre le mouvement du doigt

    13) Définir une variable d'instance touchLocation dans le viewController

    <br />#import &lt;UIKit/UIKit.h&gt;<br /><br />@interface VicoViewController : UIViewController {<br />	CGPoint touchLocation;<br />}<br /><br />@end<br />
    


    14) Repérer le rectangle à  dessiner dans touchesBegan et touchesMoved

    <br />- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {<br />	UITouch * touch=[touches anyObject];<br />	touchLocation=[touch locationInView:self.view];<br />	NSLog(NSStringFromCGPoint(touchLocation));<br />}<br /><br />- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {<br />	UITouch * touch=[touches anyObject];<br />	CGPoint location=[touch locationInView:self.view];<br />	CGSize size;<br />	size.width=location.x-touchLocation.x;<br />	size.height=location.y-touchLocation.y;<br />	<br />	CGRect rect;<br />	rect.origin=touchLocation;<br />	rect.size=size;<br />	<br />	[(VicoView*)(self.view) setRectToDraw:rect];<br />	[self.view setNeedsDisplay]; 	<br />}<br /><br />- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {<br />	NSLog(@&quot;touch ended&quot;);<br />}<br />
    


    15) Build and Run .. That's all


    Continuer :
    • Insérer une image dans le group Resources
    • Ouvrir le xib, et positionner cette image sur la vue (panel Libray>Media)
    • Faire bouger l'image avec le doigt


    • Voir l'utilisation du clip path
    • Faire une tâche à  l'écran
    • L'agrandir avec le doigt
  • Philippe49Philippe49 Membre
    avril 2009 modifié #6
    A vous de Jouer

    Vos questions à  venir , vos solutions pour les exemples ...
  • mefystomefysto Membre
    20:41 modifié #7
    J'ai un petit soucis aux etapes 8 et 9 ( je précise que je ne fais que copier le code pour voir comment tout fonctionne ensemble )
    //
    //  VicoView.m
    //  Vico
    //
    //  Created by turpin on 15/04/09.
    //  Copyright 2009 bejoga. All rights reserved.
    //

    #import "VicoView.h"


    #import "VicoViewController.h"

    #import "VicoView.h"

    @implementation VicoView
    @synthesize rectToDraw;

    @implementation VicoViewController
    @end


    - (void)drawRect:(CGRect)rect {

    CGContextRef context=UIGraphicsGetCurrentContext();

    // CGRect r;

    // r.origin.x=10.; r.origin.y=30.;

    // r.size.width=100.; r.size.height=130.;



    CGContextSetRGBFillColor(context, 1., 0., 0., 1.);

    CGContextFillRect (context,rectToDraw);

    }


    - (void)dealloc {
        [super dealloc];
    }
    - (void)drawRect:(CGRect)rect {
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGRect r;
    r.origin.x=10.; r.origin.y=30.;
    r.size.width=100.; r.size.height=130.;
    CGContextSetRGBFillColor(context, 1., 0., 0., 1.);
    CGContextFillRect (context,r);
    }


    @end









    Voici le code de ma VicoView.m
    J'ai une erreur qui dit method definition not in @implementation context
    et un warning pour @end missing ( alors qu'il y est c'est tout au debut )

    Comment faire ?
    merci d'avance




  • Philippe49Philippe49 Membre
    avril 2009 modifié #8
    Tu mélanges plusieurs codes dans un seul fichier, cela ne peut pas marcher.
    Tu dois avoir six fichiers différents  VicoAppDelegate.h et .m , VicoViewController.h et .m , VicoView.h et .m
    Et le code se répartit entre ces différents fichiers.
    Je crois qu'il te faut reprendre dès le départ pour attribuer correctement le code.

    dans 1239800822:

    Voici le code de ma VicoView.m
    J'ai une erreur qui dit method definition not in @implementation context
    et un warning pour @end missing ( alors qu'il y est c'est tout au debut )

    Le message t'indique une mauvaise gestion des @implementation et @end.

    Dans un fichier .m, on trouve (dans un modèle de base) une et une seule fois @implementation et @end

    Dans un fichier .h, on trouve (dans un modèle de base) une et une seule fois @interface et @end




  • Nebuchad34Nebuchad34 Membre
    20:41 modifié #9
    Pour info, le dernier cours de Stanford sur la programmation iPhone évoque justement le dessin avec CGPath et Context.

    Le cours n°5 enquestion n'est pas encore disponible sur iTunes, mais j'ai déjà  récupéré le pdf ici : http://www.stanford.edu/class/cs193p/cgi-bin/index.php

    Quoi qu'il en soit ces cours sont très bien pour qui veut découvrir la programmation sur iPhone (et cocoa en général). Certes c'est limité aux personnes à  l'aise en anglais, mais le fait d'avoir un ingénieur Apple devant un tableau pour nous faire un cours rend la chose évidemment plus captivante que n'importe quel bouquin.

    A bon entendeur...
  • mefystomefysto Membre
    20:41 modifié #10
    Merci beaucoup pour vos réponses , je comprend mieux maintenant.
    J'esseyerais de comprendre le tuto de stanford.
    Sinon phillipe j'ai melanger les codes car dans ton tuto tu ne dit pas où les mettre. Cela peux te paraitre évident mais pour moi et les autres "très" débutants c'est difficile.
  • Philippe49Philippe49 Membre
    avril 2009 modifié #11
    dans 1239993293:

    Sinon phillipe j'ai melanger les codes car dans ton tuto tu ne dit pas où les mettre. Cela peux te paraitre évident mais pour moi et les autres "très" débutants c'est difficile.

    Merci de le signaler, je vais préciser !

    [EDIT] Voilà 
  • DrakenDraken Membre
    20:41 modifié #12
    Excellent tuto pour apprendre les bases de la programmation graphique sur iPhone.

    Une question cependant, comment faire pour disposer de la totalité de l'écran pour dessiner ? Comment désactiver la barre de statut en haut, qui "mange" une partie de l'écran ?


  • Philippe49Philippe49 Membre
    20:41 modifié #13
    Solution 1
    Sélectionner info.plist
    Sélectionner une des lignes, appuyer sur le + tout à  droite
    Ajouter dans la colonne de gauche UIStatusBarHidden
    Dans la colonne de droite mettre à  YES.


    Solution 2
    Dans applicationDidFinishLaunching du delegate de l'UIApplication (VicoAppDelegate) mettre

    - (void)applicationDidFinishLaunching:(UIApplication *)application  {
          application.statusBarHidden=YES;
          ...
    }
  • DrakenDraken Membre
    20:41 modifié #14
    ça marche. Merci beaucoup !

  • DrakenDraken Membre
    juin 2009 modifié #15
    Et hop, une question de plus..

    J'ai voulu initialiser la couleur d'un rectangle. Pour ce faire, j'ai inséré une ligne de code dans la méthode iniWithFrame() de la View. Si j'ai bien compris, cette méthode est appelée lors de l'initialisation de la View. Cela n'a pas fonctionné.

    J'ai recréé un projet vierge en suivant la procédure décrite au début du tuto,  en insérant un NSLog() dans initWithFrame, pour tester à  vif.

    - (id)initWithFrame:(CGRect)frame {<br />	NSLog(@&quot;Initialisation&quot;);<br />&nbsp; &nbsp; if (self = [super initWithFrame:frame]) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // Initialization code<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}
    


    Et surprise, le texte "Initialisation" n'apparaà®t pas sur la console, montrant que la séquence d'initialisation ne se fait pas.

    Afin de vérifier j'ai inséré un autre NSLog() dans la méthode drawRect(). Et là  le texte "Draw.." s'affiche bien sur la console.

    - (void)drawRect:(CGRect)rect {<br />&nbsp; &nbsp; // Drawing code<br />	NSLog(@&quot;Draw..&quot;);<br />}
    


    Y a-t-il quelque chose que je n'ai pas compris sur l'utilisation de initWithFrame() ?

  • Philippe49Philippe49 Membre
    juin 2009 modifié #16
    dans 1243878612:

    Si j'ai bien compris, cette méthode est appelée lors de l'initialisation de la View. Cela n'a pas fonctionné.

    Non, elle n'est pas appelée. Le fichier xib est une archive (un peu comme un .zip pour expliquer par une image, simple image d'ailleurs car je ne sais pas si il y a une compression en cause), lors du lancement de l'application les UIView sont désarchivées via initWithCoder: et non initialisées via initWithFrame.
    Seules les UIView créées par du code vont en général être initialisées par initWithFrame:
  • Philippe49Philippe49 Membre
    20:41 modifié #17
    Pour une initialisation complémentaire d'un objet "extrait" de l'archive du xib, ObjectiveC-Cocoa prévoit la méthode -(void) awakeFromNib  qui est appelée sur chaque élément du xib après que le désarchivage total soit réalisé.

    -(void) awakeFromNib {
    NSLog(@Initialisations Complémentaires);

    }

  • DrakenDraken Membre
    20:41 modifié #18
    Je vois. Merci de l'explication. Ca me semblait assez étrange sur le moment.

    Je vais tenter l'awakeFromNib méthode !

  • CeetixCeetix Membre
    20:41 modifié #19
    J'up ce postcar là  j'arrive à  dessiner un cercle. J'aimerai en dessiner plusieur mais qu'ils restent tous à  l'écran. Je me suis donc dit qu'à  chaque fois que je dessine un nouveau cercle je l'ajoute à  un MutableArray.

    Sauf quej e dessine comme ça :

    <br />CGContextRef context = UIGraphicsGetCurrentContext();<br />	<br />	<br />	CGContextSetRGBFillColor(context, 0, 1, 0, 1); <br />	CGContextFillEllipseInRect(context, CGRectMake(x,y, 40, 40));<br />
    


    Je vois pas comment ajouter ça à  mon tableau et encore moins comment ré-appeler pour tout dessiner ...
  • Philippe49Philippe49 Membre
    20:41 modifié #20
    Définir une structure C {CGPoint center;CGFloat radius;} et stocker des NSValue dans la NSMutableArray me semble rigolo.
    Autrement tu peux encapsuler tes données dans un NSObject.
  • CeetixCeetix Membre
    20:41 modifié #21
    J'avaisp as vu ton message Philippe. J'ai trouvé tout seul et j'ai fait presque comme tu as dit. J'ai créé une classe NSObject qui contient ces infos plus la couleur.
    Merci quand même ;)
  • Philippe49Philippe49 Membre
    20:41 modifié #22
    dans 1247483679:

    ... J'ai trouvé tout seul et j'ai fait presque comme tu as dit ...

    C'est le métier qui rentre !
  • Jennifer75aJennifer75a Membre
    20:41 modifié #23
    Bonjour,

    vous trouverez sur mon site plein de tutos DONC un qui ressemble beaucoup. Je décrit pas à  pas toutes les étapes.

    http://web.me.com/jennifer.aubinais/

    Jennifer
  • DrakenDraken Membre
    20:41 modifié #24
    dans 1239001529:

    Localiser un touch

    Ne pas oublier de cocher "User Interaction Enabled" sur la vue dans IB.
    (Commentaires d'Aligator)

    11) Mettre dans VicoViewController.m la méthode suivante :
    <br />- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {<br />	UITouch * touch=[touches anyObject];<br />	CGPoint touchLocation=[touch locationInView:self.view];<br />	NSLog(NSStringFromCGPoint(touchLocation));<br />}<br />
    


    12) Build and run et ouvrir la console : On doit y voir les coordonnées du point de contact, que l'on peut contrôler par rapport au rectangle rouge présent dans la vue.


    Les "explications d'Aligator" mènent à  une page vendant l'ancien nom de domaine de pommedev.  ???

  • DrakenDraken Membre
    janvier 2011 modifié #26
    Yes sir !

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