Ecrire dans une vue ????

Jennifer75aJennifer75a Membre
19:27 modifié dans API UIKit #1
Bonjour,

Apple écrit se code :
void MyDrawText (CGContextRef myContext, CGRect contextRect) // 1
{
  float w, h;
    w = contextRect.size.width;
    h = contextRect.size.height;
    CGAffineTransform myTextTransform; // 2
    CGContextSelectFont (myContext, // 3
"Times-Bold",
h/10,
kCGEncodingMacRoman);
    CGContextSetCharacterSpacing (myContext, 10); // 4
    CGContextSetTextDrawingMode (myContext, kCGTextFillStroke);
    CGContextSetRGBFillColor (myContext, 0, 1, 0, .5); // 6
    CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1); // 7
    myTextTransform =  CGAffineTransformMakeRotation  (0); // 8
    CGContextSetTextMatrix (myContext, myTextTransform); // 9
    CGContextShowTextAtPoint (myContext, 40, 0, "Quartz 2D", 9); // 10
}
pour CGRect contextRect, c'est ok
MAIS pour myContext, il est nul ??? je le crée par CGContextRef myContext = UIGraphicsGetCurrentContext(); par il est nul

Merci de votre aide

Jennifer

Réponses

  • Philippe49Philippe49 Membre
    19:27 modifié #2
    Il faut placer un tel code dans un -(void)drawRect:(CGRect) rect, ou appelé depuis cette méthode afin que le current graphics context ait été créé.
  • Jennifer75aJennifer75a Membre
    19:27 modifié #3
    J'ai fait ce code mais cela ne fonctionne toujours pas

    -(void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSelectFont (ctx, "Times-Bold", 10, kCGEncodingMacRoman); 
    CGContextSetCharacterSpacing (ctx, 10); 
    CGContextSetTextDrawingMode (ctx, kCGTextFillStroke);
    CGContextSetRGBFillColor (ctx, 0, 1, 0, .5);
    CGContextSetRGBStrokeColor (ctx, 0, 0, 1, 1);
    CGContextShowTextAtPoint (ctx, 40, 0, "Quartz 2D", 9);
    }

    Merci de votre aide

    Jennifer
  • Jennifer75aJennifer75a Membre
    19:27 modifié #4
    GAGNE

    j'ai trouvé
    Je vais faire un tuto sur mon site
    http://web.me.com/jennifer.aubinais/

    Bon week-end

    Jennifer
  • Philippe49Philippe49 Membre
    mai 2009 modifié #5
    1) Pour dessiner du texte dans une vue
    Les NSString (UIKit Addition) fournissent un certain nombre de méthodes commençant par drawAtPoint et par drawInRect:

    - (CGSize)drawAtPoint:(CGPoint)point withFont:(UIFont *)font;<br />- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font;<br />- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode;<br />- (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width withFont:(UIFont *)font fontSize:(CGFloat)fontSize lineBreakMode:(UILineBreakMode)lineBreakMode baselineAdjustment:(UIBaselineAdjustment)baselineAdjustment;<br />...
    


    2) Pour utiliser directement Core Graphics,
    Un petit piège : le texte est à  l'envers. On utilise la matrice de rotation.
    Dès lors un ajustement sur l'ordonnée du point origine s'avère nécessaire.
    - (void)drawRect:(CGRect)rect {<br />	CGContextRef ctx = UIGraphicsGetCurrentContext();<br />	CGContextSetRGBStrokeColor (ctx, 1., 0., 0., 1.); <br />	CGContextSetRGBFillColor (ctx, 1., 0., 0, 1.);<br />	<br />	// choix de la police<br />	CGContextSelectFont (ctx, &quot;Helvetica&quot;, 12, kCGEncodingMacRoman);  <br />	UIFont * font=[UIFont fontWithName:@&quot;Helvetica&quot; size:12.];<br /><br />	// Symétrie par rapport à  un axe horizontal<br />	CGContextSetTextMatrix (ctx, CGAffineTransformMake (1,0,0,-1,0,0));<br /><br />	// Ecriture au point voulu startText <br />	CGPoint startText=CGPointMake(10.,50.);<br />	CGContextShowTextAtPoint (ctx, startText.x, startText.y+[font ascender], &quot;Quartz&quot;,6); <br /><br />	// Vérification par encadrement par un rectangle<br />	CGSize size=[@&quot;Quartz&quot; sizeWithFont:font];<br />	CGContextStrokeRect(ctx,CGRectMake(startText.x, startText.y,size.width,size.height));<br />
    


    Ton code ne marchait pas car la police "Times-Bold" n'est pas utilisable sous iPhone.
  • Philippe49Philippe49 Membre
    19:27 modifié #6
    Pour obtenir la liste des font utilisables, on a la méthode familyNames de UIFont. A ce jour (iPhone OS 3.0)

    2009-05-08 23:32:27.358 Untitled[3795:20b] (<br />&nbsp; &nbsp; AppleGothic,<br />&nbsp; &nbsp; &quot;Hiragino Kaku Gothic ProN&quot;,<br />&nbsp; &nbsp; &quot;Arial Unicode MS&quot;,<br />&nbsp; &nbsp; &quot;Heiti K&quot;,<br />&nbsp; &nbsp; &quot;DB LCD Temp&quot;,<br />&nbsp; &nbsp; Helvetica,<br />&nbsp; &nbsp; &quot;Marker Felt&quot;,<br />&nbsp; &nbsp; &quot;Times New Roman&quot;,<br />&nbsp; &nbsp; Verdana,<br />&nbsp; &nbsp; Georgia,<br />&nbsp; &nbsp; &quot;Arial Rounded MT Bold&quot;,<br />&nbsp; &nbsp; &quot;Trebuchet MS&quot;,<br />&nbsp; &nbsp; &quot;Heiti TC&quot;,<br />&nbsp; &nbsp; &quot;Geeza Pro&quot;,<br />&nbsp; &nbsp; Courier,<br />&nbsp; &nbsp; Arial,<br />&nbsp; &nbsp; &quot;Heiti J&quot;,<br />&nbsp; &nbsp; &quot;Arial Hebrew&quot;,<br />&nbsp; &nbsp; &quot;Courier New&quot;,<br />&nbsp; &nbsp; Zapfino,<br />&nbsp; &nbsp; &quot;American Typewriter&quot;,<br />&nbsp; &nbsp; &quot;Heiti SC&quot;,<br />&nbsp; &nbsp; &quot;Helvetica Neue&quot;,<br />&nbsp; &nbsp; Thonburi<br />)
    

  • muqaddarmuqaddar Administrateur
    19:27 modifié #7
    Bonjour,

    J'ai créé une vue et je voudrais également écrire dedans.
    J'arrive à  écrire des choses simples avec CoreGraphics (je fais mes débuts avec cette API).

    Je souhaiterais maintenant appliquer une rotation autour d'un centre pour le texte que j'écris (une série de strings).

    J'ai réussi à  faire ces choses là  auparavant avec des UILabels et leurs layers, mais question perfs c'est très moyen. Je suis donc passé à  CoreGraphics...

    Donc j'ai une frame de 400 pixels de côté (0,0,400,400).

    Je veux faire graviter du texte autour de cette frame mais j'ai du mal à  positionner ces éléments en rotation car la méthode CGContextShowTextAtPoint (ctx, startText.x, startText.y, text, length) permet de placer du texte à  un point, sauf que je voudrais faire une rotation autour du point ancre situé à  200,200... au coeur de la frame, alors que le texte initial est situé en 380, 200 par exemple.

    Avec les layers et les anchors points, c'était très facile. Mais là  je sèche. Il n'y a pas de méthode équivalente à  drawInRect en CG ? Et une autre pour positionner un point d'origine pour faire la rotation ?

    Je n'ai pas su me dépatouiller avec : CGAffineTransformMakeRotation(newPos);
    CGContextRotateCTM(ctx, newPos);
  • AliGatorAliGator Membre, Modérateur
    mai 2009 modifié #8
    Utiliser les NSString UIKit Additions ne te faciliterai pas la tâche par hasard ?

    Sinon il faut que tu joues sur les CGAffineTransform pour positionner ton texte, en composant les différentes transformation (sans doute une translation pour amener le centre de ta NSString au centre de ta vue, puis la rotation, puis re une translation pour repositionner ta NSString rotationnée au bon endroit)... en composant dans le bon sens, on finit par y arriver (après plusieurs tâtonnements en général :P)
  • Philippe49Philippe49 Membre
    mai 2009 modifié #9
    Cela n'est pas encore parfait, il faut ajuster parce que le point d'écriture à  gauche ne suit pas la même règle que le point d'écriture à  droite

    <br />// Symétrie par rapport à  un axe horizontal<br />	CGAffineTransform transform= CGAffineTransformMake (1,0,0,-1,0,0);<br />	CGFloat radius = 0.3*MAX(CGRectGetWidth(self.frame),CGRectGetHeight(self.frame));<br />	NSInteger N=[string length];<br />	for(NSInteger i=0;i&lt;N;i++){<br />		CGAffineTransform currentTransform=CGAffineTransformRotate(transform,M_PI/2.-i*M_PI/(N-1));<br />		CGContextSetTextMatrix (ctx,currentTransform);	<br />		CGPoint startText=CGPointMake(self.center.x+radius*cos((N-1-i)*M_PI/(N-1)),self.center.y-radius*sin((N-1-i)*M_PI/(N-1)));<br />		char text[2]=&quot;&quot;;<br />		text[0]=[string characterAtIndex:i];<br />		CGContextShowTextAtPoint (ctx, startText.x, startText.y,text,1);<br />	}<br />
    


    Bon, j'ai fait des maths toute la jour née un peu le tour aux autres non ?  ;D
  • muqaddarmuqaddar Administrateur
    19:27 modifié #10
    @ ali : je pourrais utiliser drawInRect, mais il faut quand même lui dire de caler le texte à  droite du rect dans mon cas, et faire la rotation.

    @ philippe, boudiou c'est bien confus... je n'arrive pas à  modifier ta base pour en faire ce que je veux.

    Je cherche l'équivalent de ceci (qui marche super bien, mais qui rame au chargement car 64 layers !) :

    int i;	<br />	for(i=1; i &lt;= 64; i++) {		<br />		UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectZero];	<br />		textLabel.backgroundColor = [UIColor clearColor];<br />		textLabel.font = [UIFont systemFontOfSize:14.0];<br />		textLabel.textColor = [UIColor blackColor];<br />		textLabel.textAlignment = UITextAlignmentRight;<br />		textLabel.layer.frame = CGRectMake(0, 200, 416, 16);<br />		textLabel.layer.anchorPoint = CGPointMake(0.5, 0.5);<br />		textLabel.text = [NSString stringWithFormat:@&quot;%d&nbsp; &nbsp; &quot;, i];	<br />		[self.view addSubview:textLabel];	<br />		[_imageLayer addSublayer:textLabel.layer];<br />		float newPos = (((-2*M_PI) / 64) * i) + M_PI/64;<br />		textLabel.layer.transform = CATransform3DMakeRotation(newPos, 0.0f, 0.0f, 1.0f);<br />		[textLabel release];<br />	}
    


    C'est donc pour obtenir un cercle de chiffres autour d'une roue...
  • Philippe49Philippe49 Membre
    19:27 modifié #11
    Meuh non c'est pas confus ...  :)

    - (void)drawRect:(CGRect)rect {<br />	CGContextRef ctx = UIGraphicsGetCurrentContext();<br />	CGContextSetRGBFillColor (ctx, 1., 0., 0., 1.);<br />	<br />	// choix de la police<br />	CGContextSelectFont (ctx, &quot;Helvetica&quot;, 24, kCGEncodingMacRoman); <br />	UIFont * font=[UIFont fontWithName:@&quot;Helvetica&quot; size:24.0]; <br />	CGFloat h;<br />	<br />	// Symétrie par rapport à  un axe horizontal<br />	CGAffineTransform transform= CGAffineTransformMake (1,0,0,-1,0,0);<br />	CGFloat radius = 0.3*MAX(CGRectGetWidth(self.frame),CGRectGetHeight(self.frame));<br />	<br />	NSInteger N=[string length];<br />	for(NSInteger i=0;i&lt;N;i++){<br />		NSString * text=[string substringWithRange:NSMakeRange(i,1)];<br />		// calcul de la poistion d&#39;écriture<br />		h=[text sizeWithFont:font].width/2.0;<br />		CGFloat theta=M_PI-i*M_PI/(N-1);<br />		CGPoint midText;<br />		midText.x=self.center.x+radius*cos(theta);<br />		midText.y=self.center.y-radius*sin(theta);<br />		CGPoint startText;<br />		startText.x=midText.x-h*sin(theta);<br />		startText.y=midText.y-h*cos(theta);<br />		// rotation du texte<br />		CGAffineTransform currentTransform=CGAffineTransformRotate(transform,M_PI/2.-i*M_PI/(N-1));<br />		CGContextSetTextMatrix (ctx,currentTransform);	<br />	<br />		CGContextShowTextAtPoint (ctx, startText.x, startText.y,[text UTF8String],1);<br />		<br />		CGContextMoveToPoint(ctx, self.center.x, self.center.y);<br />		CGContextAddLineToPoint(ctx, midText.x, midText.y);<br />	}<br />	CGContextSetRGBStrokeColor (ctx, 0., 0., 0.8, 1.);	<br />	CGContextDrawPath(ctx,kCGPathStroke);<br />	<br />}<br />
    
  • Philippe49Philippe49 Membre
    mai 2009 modifié #12
    Et en changeant
    <br />	CGFloat theta=M_PI-i*2*M_PI/N;<br />....<br />	CGAffineTransform currentTransform=CGAffineTransformRotate(transform,M_PI/2.-i*2*M_PI/N);
    


    [EDIT] Hurks, j'avios pas mis la bonme photo ! 
  • Philippe49Philippe49 Membre
    19:27 modifié #13
    Alors ? Heureux ??
    [move] :o :o :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf):  :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o[/move]
  • muqaddarmuqaddar Administrateur
    19:27 modifié #14
    dans 1243285433:

    Alors ? Heureux ??
    [move] :o :o :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf): :fouf):  :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o :o[/move]



    Je fais mes modifs et je te dis ça... ;) héhé
    Meci à  toi en tout cas !!!
  • muqaddarmuqaddar Administrateur
    mai 2009 modifié #15
    Voilà  ton code reformatté pour mon cas :

    - (void)drawNumbers<br />{<br />	// create context<br />	CGContextRef ctx = UIGraphicsGetCurrentContext();<br />	// set color<br />	CGContextSetRGBFillColor(ctx, 0., 0., 0., 1.);<br />	// show font<br />	CGContextSelectFont(ctx, &quot;Helvetica&quot;, 14, kCGEncodingMacRoman); <br />	UIFont *font = [UIFont fontWithName:@&quot;Helvetica&quot; size:14.0]; <br />	// vars<br />	CGFloat h;<br />	CGFloat theta;<br />	CGPoint midText;<br />	CGPoint startText;<br />	<br />	// symétrie par rapport à  un axe horizontal<br />	CGAffineTransform transform = CGAffineTransformMake(1,0,0,-1,0,0);<br />	CGFloat radius = 0.42 * MAX(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));<br />	<br />	for (NSInteger i=1; i&lt;65; i++) {<br />		<br />		NSString *text = [NSString stringWithFormat:@&quot;%d&quot;, i];<br />		<br />		// calcul de la position d&#39;écriture<br />		h = [text sizeWithFont:font].width/2.0;<br />		// bidouille si 2 caractères...<br />		if ([text length] == 2) h = h - 4;<br />		<br />		// angle en radians<br />		theta = (((2*M_PI) / 64) * i) - M_PI/32;<br />		<br />		// position du texte<br />		midText.x = self.center.x + radius*cos(theta);<br />		midText.y = self.center.y - radius*sin(theta);			<br />		startText.x = midText.x - h*sin(theta);<br />		startText.y = midText.y - h*cos(theta);<br />			<br />		// rotation du texte<br />		CGAffineTransform currentTransform = CGAffineTransformRotate(transform, theta);<br />		CGContextSetTextMatrix (ctx,currentTransform);	<br />		<br />		// ecriture du texte<br />		CGContextShowTextAtPoint (ctx, startText.x, startText.y, [text UTF8String], [text length]);<br />		<br />	}<br />		<br />}
    


    Note la bidouille si j'ai 2 cars à  afficher au lieu d'un... doit sûrement y avoir plus propre !
    En tout cas, je te remercie. Il me semble que c'est plus fluide maintenant. Surtout que cette vue est destinée à  tourner... ;)

    Un grand merci pour ton aide ! 
  • Philippe49Philippe49 Membre
    19:27 modifié #16
    dans 1243288695:

    Note la bidouille si j'ai 2 cars à  afficher au lieu d'un... doit sûrement y avoir plus propre !

    Curieux , j'ai pris la moitié de la largeur du texte. Le centre de la rotation du texte peut-être ?
    Quel effet cela donnait-il avec 2 caractères ?

    dans 1243288695:

    Il me semble que c'est plus fluide maintenant. Surtout que cette vue est destinée à  tourner... ;)

    Ce ne serait pas plus fluide avec une image définie soit en ressource, soit enregistrée une fois pour toutes par du code , plutôt que de la redessiner à  chaque fois ?
  • muqaddarmuqaddar Administrateur
    19:27 modifié #17
    1) Si je ne fais pas la bidouille, le texte est décalé en position Y de quelques pixels (X aussi ?), donc il n'est plus en face de mes cases.

    2) Oui j'ai une image de fond sur laquelle je greffe cette vue. Mais comme je n'ai pas trouvé un bon logiciel capable de faire des rotations de texte au centième de degré (5,625° par chiffre dans mon cas), je le fais pas programmation pour plus de précision. Photoshop s'arrête aux dizièmes par exemple. De plus c'est moin galère à  placer, et au final, j'ai fait mes début avec CG...
  • Philippe49Philippe49 Membre
    19:27 modifié #18
    dans 1243349239:

    1) Si je ne fais pas la bidouille, le texte est décalé en position Y de quelques pixels (X aussi ?), donc il n'est plus en face de mes cases.

    Il faut sans doute rentrer plus à  fond dans la métrique des fonts pour faire le calcul exact , cf l'instruction
    CGContextShowTextAtPoint (ctx, startText.x, startText.y+[font ascender], "Quartz",6);
    que j'avais du mettre plus haut pour bien insérer le texte dans le rectangle après la symétrie verticale. A améliorer donc ...

    dans 1243349239:

    2) Oui j'ai une image de fond sur laquelle je greffe cette vue. Mais comme je n'ai pas trouvé un bon logiciel capable de faire des rotations de texte au centième de degré (5,625° par chiffre dans mon cas), je le fais pas programmation pour plus de précision. Photoshop s'arrête aux dizièmes par exemple. De plus c'est moin galère à  placer, et au final, j'ai fait mes début avec CG...

    Je pensais à  dessiner le motif sur une image vierge une fois pour toutes par le code, puis à  faire tourner cette image ensuite.
  • muqaddarmuqaddar Administrateur
    mai 2009 modifié #19
    dans 1243349239:

    1) Si je ne fais pas la bidouille, le texte est décalé en position Y de quelques pixels (X aussi ?), donc il n'est plus en face de mes cases.
    Il faut sans doute rentrer plus à  fond dans la métrique des fonts pour faire le calcul exact , cf l'instruction
    CGContextShowTextAtPoint (ctx, startText.x, startText.y+[font ascender], "Quartz",6);
    que j'avais du mettre plus haut pour bien insérer le texte dans le rectangle après la symétrie verticale. A améliorer donc ...


    Je reviendrais dessus après release de l'application.

    dans 1243349983:

    dans 1243349239:

    2) Oui j'ai une image de fond sur laquelle je greffe cette vue. Mais comme je n'ai pas trouvé un bon logiciel capable de faire des rotations de texte au centième de degré (5,625° par chiffre dans mon cas), je le fais pas programmation pour plus de précision. Photoshop s'arrête aux dizièmes par exemple. De plus c'est moin galère à  placer, et au final, j'ai fait mes début avec CG...


    Je pensais à  dessiner le motif sur une image vierge une fois pour toutes par le code, puis à  faire tourner cette image ensuite.


    Ah, ok, oui c'est une solution, ça m'apprendrait à  "burner" une image. ;)
    D'ailleurs, sans transition, l'image actuelle est appellée par un viewController lors d'un push navigation controller, sauf que comme l'image est placée en X à  - 200 pixels, elle déborde sur la vue du navigation controller précédent lors de l'appel. Ce n'est pas un bug, c'est tout simplement logique, je dirai que ça a son charme... je pense que je pourrais à  la limite tronquer l'image lors du chargement, et recharger l'image entière lorsque je m'en sers dans la vue courante.
Connectez-vous ou Inscrivez-vous pour répondre.