Search code examples
objective-cpositionrotationquartz-2d

Draw rotated text to parent coordinate system


I have a UIView, which I'm drawing manually in the 'drawRect'-Function. It is basically a coordinate system, which has 'Values' on the Y-Axis and 'Time' on the 'X-Axis'.

Due to space issues, I want the Timestamps to be vertical, instead of horizontal. For this purpose, I use:

CGContextSaveGState(ctx);              //Saves the current graphic context state
CGContextRotateCTM(ctx, M_PI_2);       //Rotates the context by 90° clockwise
strPos = CGContextConvertPointToUserSpace(ctx, strPos); //SHOULD convert to Usercoordinates
[str drawAtPoint:strPos withFont:fnt]; //Draws the text to the rotated CTM
CGContextRestoreGState(ctx);           //Restores the CTM to the previous state.

ctx (CGContextRef), strPos (CGPoint) and str (NSString) are variables, that have been initialized properly and correctly for 'horizontal text', with a width of the text height.

While this code works flawlessly on the iPhone 3, it gives me a complete mess on the iPhone 4 (Retina), because the CGContextConvertPointToUserSpace function produces completely different results, even though the coordinate system of the iPhone is supposed to remain the same.

I also tried using CGAffineTransform, but only with the same results.

To summarize my question: How do I draw a text to a calculated position in the parent coordinate system (0, 0 being top left)?


After studying the Apple docs regarding Quartz 2D once more, I came to realize, that the rotation by Pi/2 moves all my writing off screen to the left.

I can make the writing appear in a vertical line by translating the CTM by +height. I'll keep trying, but would still be happy to get an answer.

Edit: Thanks to lawicko's heads-up I was able to fix the problem. See Answer for details.


Solution

  • I would like to thank lawicko for pointing this out. During my tests I made two mistakes...but he is of course correct. Using CGContextShowTextAtPoint is the most simple solution, since it doesn't require the rotation of the entire CTM.

    Again, THANK you. Now, for the actual answer to my question. To draw a rotated text at position x/y, the following code works for me.

    CGAffineTransform rot = CGAffineTransformMakeRotation(M_PI_2);    //Creates the rotation
    CGContextSelectFont(ctx, "TrebuchetMS", 10, kCGEncodingMacRoman); //Selects the font
    CGContextSetTextMatrix(ctx, CGAffineTransformScale(rot, 1, -1));  //Mirrors the rotated text, so it will be displayed correctly.
    CGContextShowTextAtPoint(ctx, strPos.x, strPos.y, TS, 5);         //Draws the text
    

    ctx is the CGContext, strPos the desired position in the parent coordinate system, TS a char array.

    Again, thank you lawicko. I probably would've searched forever if not for your suggestion. Maybe this answer will help someone else, who comes across the same problem.