views:

908

answers:

4

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.

  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

+1  A: 

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

Epsilon Prime
I do know about `tableView:heightForRowAtIndexPath:`, the row itself is fine. The text is getting clipped during the transform and ends up cut off in the middle of the cell.
Sidnicious
Could you show us the specific code you use to do the transform?
Epsilon Prime
+2  A: 

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.

mahboudz
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
+2  A: 

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.

Sidnicious
A: 

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

dny238