2009-11-09 5 views
5

Je veux dessiner du texte dans une vue, tourné de 90 °. Je suis un nouveau venu dans le développement de l'iPhone, et le fait de fouiller le web révèle un certain nombre de solutions différentes. J'en ai essayé quelques-uns et finit généralement avec mon texte se couper.iPhone: dessiner un texte pivoté?

Que se passe-t-il ici? I suis dessin dans un espace assez petit (une cellule de vue de table), mais il doit y avoir une "bonne" façon de le faire ... non?


Edit: Voici quelques exemples. J'essaie d'afficher le texte "" le long de la barre noire à gauche.

  1. Première tentative, de RJShearman on the Apple Discussions

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSelectFont (context, "Helvetica-Bold", 16.0, kCGEncodingMacRoman); 
    CGContextSetTextDrawingMode (context, kCGTextFill); 
    CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0); 
    CGContextSetTextMatrix (context, CGAffineTransformRotate(CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f), M_PI/2)); 
    CGContextShowTextAtPoint (context, 21.0, 55.0, [_cell.number cStringUsingEncoding:NSUTF8StringEncoding], [_cell.number length]); 
    CGContextRestoreGState(context); 
    

    Attempt one. The one and part of the two are clipped out. http://dev.deeptechinc.com/sidney/share/iphonerotation/attempt1.png

  2. deuxième tentative, de zgombosi on iPhone Dev SDK. Résultats identiques (la police était légèrement plus petite ici, donc il y a moins d'écrêtage).

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGPoint point = CGPointMake(6.0, 50.0); 
    CGContextSaveGState(context); 
    CGContextTranslateCTM(context, point.x, point.y); 
    CGAffineTransform textTransform = CGAffineTransformMakeRotation(-1.57); 
    CGContextConcatCTM(context, textTransform); 
    CGContextTranslateCTM(context, -point.x, -point.y); 
    [[UIColor redColor] set]; 
    [_cell.number drawAtPoint:point withFont:[UIFont fontWithName:@"Helvetica-Bold" size:14.0]]; 
    CGContextRestoreGState(context); 
    

    Attempt two. There is almost identical clipping http://dev.deeptechinc.com/sidney/share/iphonerotation/attempt2.png

+0

Il existe en effet plusieurs façons d'y parvenir. Fournir des détails sur ce que vous avez exactement essayé et comment cela n'a pas fonctionné (comment/où a-t-il été découpé?) Rendrait la réponse plus facile. –

+0

Détail fourni. – s4y

Répondre

7

Il s'est avéré que la cellule de mon tableau était toujours initialisée 44px haut quelle que soit la hauteur de la ligne, donc tout mon dessin se faisait écrêter 44px du haut de la cellule.

Pour tirer des cellules plus grandes, il est nécessaire de définir est appelée avec la bonne taille de l'affichage du contenu autoresizingMask avec

cellContentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; 

ou

cellContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

... et drawRect. D'une certaine manière, cela est logique car initWithStyle:reuseIdentifier: ne fait aucune mention de la taille de la cellule, et seule la vue table sait réellement quelle sera la taille de chaque ligne, en fonction de sa taille et de la réponse de son délégué à tableView:heightForRowAtIndexPath: .

Je lis la Quartz 2D Programming Guide jusqu'à ce que le modèle de dessin et les fonctions ont commencé à donner un sens, et le code pour dessiner mon texte tourné est devenu simple et évidente:

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSaveGState(context); 
CGContextRotateCTM(context, -(M_PI/2)); 
[_cell.number drawAtPoint:CGPointMake(-57.0, 5.5) withFont:[UIFont fontWithName:@"Helvetica-Bold" size:16.0]]; 
CGContextRestoreGState(context); 

Merci pour les conseils, on dirait que je suis tout ensemble.

1

Vous connaissez la méthode UITableViewDelegate heightForRowAtIndexPath droit?

Voici un simple tutorial on various graphics level methods. En supposant que vous connaissiez la taille de votre texte, vous devriez pouvoir dimensionner correctement la taille de votre ligne de vue table.

En outre, je vérifie pour s'assurer que les limites après toute transformation répondent réellement à vos attentes. (Utilisez un débogueur ou une instruction de journal pour le vérifier).

+0

Je sais que 'tableView: heightForRowAtIndexPath:', la ligne elle-même est bien. Le texte est découpé pendant la transformation et finit par être coupé au milieu de la cellule. – s4y

+0

Pourriez-vous nous montrer le code spécifique que vous utilisez pour faire la transformation? –

2

Voici un conseil. Je suppose que vous faites ce dessin dans drawRect. Pourquoi ne dessinez-vous pas un cadre autour de drawRect pour voir la taille du rectangle et si c'est pour cela que vous obtenez un écrêtage.

Une alternative consiste à placer votre texte dans un UILabel, puis de faire pivoter ce dernier de 90 degrés lorsque vous créez vos cellules dans cellForRowAtIndexPath.

+2

La suggestion de mahboudz sera probablement votre chemin de moindre résistance. Vous pouvez faire pivoter UILabel 90deg avec ceci: [label setTransform: CGAffineTransformMakeRotation (DegreesToRadians (-90.0f))]; Vous devrez juste calculer la hauteur de votre cellule en fonction de la largeur de l'étiquette. -Matt –

0

Après avoir découvert que j'avais besoin d'ajouter ce qui suit au début de mon fichier, j'ai aimé l'approche de Matt. Très simple.

#define degreesToRadian(x) (M_PI * (x)/180.0) 

La suggestion de mahboudz sera probablement votre chemin de moindre résistance. Vous pouvez faire pivoter UILabel 90deg avec ceci: [label setTransform: CGAffineTransformMakeRotation (DegreesToRadians (-90.0f))]; Vous devrez juste calculer la hauteur de votre cellule en fonction de la largeur de l'étiquette. -Matt - Matt Long 10 novembre à 0:09

3

Utilisation: -

label.transform = CGAffineTransformMakeRotation(- 90.0f * M_PI/180.0f); 

où l'étiquette est l'objet de UILabel.

+0

Merci, @Sorti! En fait, je n'utilisais pas de 'UILabel' - je dessinais dans une cellule de vue de table personnalisée. – s4y

1

à ce que @Sidnicious a dit, et ce que je collectionnais par débordement de pile, je veux donner un exemple d'utilisation - joint en annexe mon code pour dessiner complètement une règle sur le côté gauche de l'écran, avec des numéros mis en rotation:

ruler screenshot

RulerView : UIView 


    // simple testing for iPhones (check for device descriptions to get all iPhones + iPads) 
    - (float)getPPI 
    { 
     switch ((int)[UIScreen mainScreen].bounds.size.height) { 
      case 568: // iPhone 5* 
      case 667: // iPhone 6 
       return 163.0; 
       break; 

      case 736: // iPhone 6+ 
       return 154.0; 
       break; 

      default: 
       return -1.0; 
       break; 
     } 
    } 

    - (void)drawRect:(CGRect)rect 
    { 
     [[UIColor blackColor] setFill]; 


     float ppi = [self getPPI]; 

     if (ppi == -1.0) // unable to draw, maybe an ipad. 
      return; 

     float linesDist = ppi/25.4; // ppi/mm per inch (regular size iPad would be 132.0, iPhone6+ 154.0) 

     float linesWidthShort = 15.0; 
     float linesWidthMid = 20.0; 
     float linesWidthLong = 25.0; 

     for (float i = 0, c = 0; i <= self.bounds.size.height; i = i + linesDist, c = c +1.0) 
     { 
      bool isMid = (int)c % 5 == 0; 
      bool isLong = (int)c % 10 == 0; 

      float linesWidth = isLong ? linesWidthLong : isMid ? linesWidthMid : linesWidthShort; 
      UIRectFillUsingBlendMode((CGRect){0, i, linesWidth, .5} , kCGBlendModeNormal); 



      /* FONT: Numbers without rotation (yes, is short) 
      if (isLong && i > 0 && (int)c % 10 == 0) 
       [[NSString stringWithFormat:@"%d", (int)(c/10)] drawAtPoint:(CGPoint){linesWidthLong +2, i -5} withAttributes:@{ 
                                   NSFontAttributeName: [UIFont systemFontOfSize:9], 
                                   NSBaselineOffsetAttributeName: [NSNumber numberWithFloat:1.0] 
                                   }]; 
      */ 


      // FONT: Numbers with rotation (yes, requires more effort) 
      if (isLong && i > 0 && (int)c % 10 == 0) 
      { 
       NSString *str = [NSString stringWithFormat:@"%d", (int)(c/10)]; 
       NSDictionary *attrs = @{ 
             NSFontAttributeName: [UIFont systemFontOfSize:9], 
             NSBaselineOffsetAttributeName: [NSNumber numberWithFloat:0.0] 
             }; 
       CGSize textSize = [str sizeWithAttributes:attrs]; 


       CGContextRef context = UIGraphicsGetCurrentContext(); 
       CGContextSaveGState(context); 

       CGContextRotateCTM(context, +(M_PI/2)); 
       [str drawAtPoint:(CGPoint){i - (textSize.width/2), -(linesWidthLong + textSize.height +2)} withAttributes:attrs]; 

       CGContextRestoreGState(context); 
      } 

     } 
    } 
Questions connexes