尝试使用CGAffineTransform和MakeRotation绘制旋转文本时出现在错误的位置

时间:2012-09-17 16:32:53

标签: xamarin.ios cgaffinetransform drawstring

我正在尝试通过在特定位置使用CGAffineTransform.MakeRotation方法绘制一些旋转的文本。我也使用了TranslateCTM,但是由于旋转的文本看起来不对齐并且在正确的x,y位置它们应该出现的地方,所以必定是错误的,这里我使用的代码很简单,任何人都知道问题在哪里? :

        public override void Draw (RectangleF rect)
    {
        DrawTextRotated("Hello1",10,100,30);
        DrawTextRotated("Hello2",50,100,60);
        SetNeedsDisplay();          
    }       

    static public float DegreesToRadians(float x) 
    {       
        return (float) (Math.PI * x / 180.0);
    }

    public void DrawTextRotated(string text,int x, int y, int rotDegree)
    {
        CGContext c = UIGraphics.GetCurrentContext();
        c.SaveState();

        c.TextMatrix = CGAffineTransform.MakeRotation((float)DegreesToRadians((float)(-rotDegree)));                        
        c.ConcatCTM(c.TextMatrix); 

        float xxx = ((float)Math.Sin(DegreesToRadians((float)rotDegree))*y);
        float yyy = ((float)Math.Sin(DegreesToRadians((float)rotDegree))*x);

        // Move the context back into the view 
        c.TranslateCTM(-xxx,yyy);

        c.SetTextDrawingMode(CGTextDrawingMode.Fill);
        c.SetShouldSmoothFonts(true);

        MonoTouch.Foundation.NSString str = new MonoTouch.Foundation.NSString(text);            
        SizeF strSize = new SizeF();
        strSize = str.StringSize(UIFont.SystemFontOfSize(12));          

        RectangleF tmpR = new RectangleF(x,y,strSize.Width,strSize.Height);

        str.DrawString(tmpR,UIFont.SystemFontOfSize(12),UILineBreakMode.WordWrap,UITextAlignment.Right);
        c.RestoreState();
    }

谢谢!

1 个答案:

答案 0 :(得分:1)

以下是一些代码,可以将文本正确旋转关于文本的左上角。目前,我无视您对文本对齐的使用。

首先,一种实用工具方法,用于绘制我们希望文本显示的标记:

public void DrawMarker(float x, float y)
{
    float SZ = 20;

    CGContext c = UIGraphics.GetCurrentContext();

    c.BeginPath();
    c.AddLines( new [] { new PointF(x-SZ,y), new PointF(x+SZ,y) });
    c.AddLines( new [] { new PointF(x,y-SZ), new PointF(x,y+SZ) });
    c.StrokePath();
}

绘制文本的代码(注意我用float替换了所有int旋转,你可能想要否定你的旋转):

public void DrawTextRotated(string text, float x, float y, float rotDegree)
{
    CGContext c = UIGraphics.GetCurrentContext();
    c.SaveState();

    DrawMarker(x,y);

    // Proper rotation about a point
    var m = CGAffineTransform.MakeTranslation(-x,-y);
    m.Multiply( CGAffineTransform.MakeRotation(DegreesToRadians(rotDegree)));
    m.Multiply( CGAffineTransform.MakeTranslation(x,y));
    c.ConcatCTM( m );

    // Draws text UNDER the point
    // "This point represents the top-left corner of the string’s bounding box."
    //http://developer.apple.com/library/ios/#documentation/UIKit/Reference/NSString_UIKit_Additions/Reference/Reference.html
    NSString ns = new NSString(text);
    UIFont font = UIFont.SystemFontOfSize(12);
    SizeF sz = ns.StringSize(font);
    RectangleF rect = new RectangleF(x,y,sz.Width,sz.Height);
    ns.DrawString( rect, font);

    c.RestoreState();
}

围绕一个点的旋转需要将点平移到原点然后旋转,然后旋转回原点。 CGContext.TextMatrixNSString.DrawString无效,因此您只需使用ConcatCTM

对齐和换行模式没有任何效果。由于您正在使用NSString.StringSize,因此边界矩形适合整个文本,紧贴左右边缘。如果您使边界矩形的宽度更宽并使用UITextAlignment.Right,您将获得正确的右对齐,但文本仍将围绕整个边界矩形的左上角旋转。不,我猜,你在期待什么。

如果您希望文本围绕右上角旋转,请告诉我,我会相应调整代码。

这是我在测试中使用的代码:

DrawTextRotated("Hello 0",100, 50, 0);
DrawTextRotated("Hello 30",100,100,30);
DrawTextRotated("Hello 60",100,150,60);
DrawTextRotated("Hello 90",100,200,90);

干杯。

相关问题