English 中文(简体)
iPhone: Draw rotated text?
原标题:

I want to draw some text in a view, rotated 90°. I m pretty new to iPhone development, and poking around the web reveals a number of different solutions. I ve tried a few and usually end up with my text getting clipped.

What s going on here? I am drawing in a fairly small space (a table view cell), but there has to be a "right" way to do this… right?


Edit: Here are a couple of examples. I m trying to display the text "12345" along the black bar at the left.

  1. First attempt, from 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.
    (source: deeptechinc.com)

  2. Second attempt, from zgombosi on iPhone Dev SDK. Identical results (the font was slightly smaller here, so there s less clipping).

    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

最佳回答

It turns out that the my table cell was always initialized 44px high regardless of the row height, so all of my drawing was getting clipped 44px from the top of the cell.

To draw larger cells it was necessary to set the content view s autoresizingMask with

cellContentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

or

cellContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

…and drawRect is called with the correct size. In a way, this makes sense, because UITableViewCell s initWithStyle:reuseIdentifier: makes no mention of the size of the cell, and only the table view actually knows how big each row is going to be, based on its own size and its delegate s response to tableView:heightForRowAtIndexPath:.

I read the Quartz 2D Programming Guide until the drawing model and functions started to make sense, and the code to draw my rotated text became simple and obvious:

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);

Thanks for the tips, it looks like I m all set.

问题回答

Use :-

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

where label is the object of UILabel.

Here s a tip. I presume you re doing this drawing in drawRect. Why don t you draw a frame around drawRect to see how big the rect is and if that is why you get clipping.

An alternative is to put your text in a UILabel, and then rotate that 90 degrees when you make your cells in cellForRowAtIndexPath.

You know about the UITableViewDelegate method heightForRowAtIndexPath right?

Here s a simple tutorial on various graphics level methods. Presuming you know how big your text is you should be able to size your table view row size appropriately.

Also, I d check to make sure that the bounds after any transform actually meet your expectations. (Either use a debugger or log statement to verify this).

to what @Sidnicious said, and what i collected through out stack overflow, i want to give a usage example - appended my code to completely draw a ruler to the left screen side, with numbers rotated:

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);
          }

      }
  }

After I discovered that I needed to add the following to the top of my file I liked Matt s approach. Very simple.

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

mahboudz s suggestion will probably be your path of least resistance. You can rotate the UILabel 90deg with this: [label setTransform:CGAffineTransformMakeRotation(DegreesToRadians(-90.0f))]; You ll just have to calculate your cell height based upon the label width. -Matt – Matt Long Nov 10 at 0:09





相关问题
Which non-bold UTF-8 iPhone SDK font can I use here?

Problem: I create a UILabel with this font: label.font = [UIFont systemFontOfSize:15.0f]; Now this system font is bold, but I want to display pretty small text, and the text may also contain very ...

Limiting file upload type

Simple question. Is there a way to only allow txt files upon uploading? I ve looked around and all I find is text/php, which allows PHP. $uploaded_type=="text/php

Extract everything from PDF [closed]

Looking for solution to extract content from a PDF file (using console tool or a library). It will be used on server to produce on-line e-books from uploaded PDF files. Need to extract following ...

Flash & external form fields

Does anybody know if this is possible? I am trying to create a flash movie that will show / preview what I am typing into a field in a normal HTML form. The call to update the flash movie would most ...

Avoiding escape sequence processing in ActionScript?

I need to mimic C# functionality of the @ symbol when it precedes a string. @"C:AFilePath" for example What is the best way to do this? Also there are some sites that will escape larger ...

iPhone: Draw rotated text?

I want to draw some text in a view, rotated 90°. I m pretty new to iPhone development, and poking around the web reveals a number of different solutions. I ve tried a few and usually end up with my ...

Numbering in jQuery

How could I change the text below so that the text within it has a number appended to it. <div class="right">This is some text</div> <div class="right">This is some text</div>...

热门标签