【问题标题】:Draw text along circular path in xamarin ios在 xamarin ios 中沿圆形路径绘制文本
【发布时间】:2017-10-17 14:03:51
【问题描述】:

我在以下链接中找到了答案: Draw text along circular path in Swift for iOS

这对我来说似乎很好。现在,我只是想在 xamarin ios 中转换相同的代码,但还没有成功。

 public class CircularText : UIView
{
    public override void Draw(CoreGraphics.CGRect rect)
    {
        base.Draw(rect);
        this.BackgroundColor = UIColor.Clear;
        var context = UIGraphics.GetCurrentContext();
        var size = this.Bounds.Size;

        context.TranslateCTM(size.Width / 2, size.Height / 2);
        context.ScaleCTM(1, -1);


        CentreArcPerpendicular(str: "Hello round world", context: context, radius: 100, angle: 0, color: UIColor.Red, font: UIFont.SystemFontOfSize(16), clockwise: true);
        CentreArcPerpendicular(str: "Anticlockwise", context: context, radius: 100, angle: (System.nfloat)(-Math.PI / 2), color: UIColor.Red, font: UIFont.SystemFontOfSize(16), clockwise: false);
        centre(str: "Hello flat world", context: context, radius: 0, angle: 0, color: UIColor.Yellow, font: UIFont.SystemFontOfSize(16), slantAngle: (System.nfloat)(Math.PI / 4));
    }

    void CentreArcPerpendicular(String str, CGContext context, nfloat radius, nfloat angle, UIColor color, UIFont font, bool clockwise)
    {
        var l = str.Length;
        char[] characters = str.ToCharArray();
        nfloat[] arcs = new nfloat[l];
        nfloat totalArc = 0;

        for (int i = 0; i < l; i++)
        {
            arcs[i] = chordToArc(1, radius);  
        }

        var direction = clockwise ? -1 : 1;
        var slantCorrection = clockwise ? -Math.PI / 2 : Math.PI;

        var thetaI = angle - direction * totalArc / 2;


        for (int i = 0; i < l; i++)
        {
            thetaI += direction * arcs[i] / 2;
            centre(str: characters[i].ToString(), context: context, radius: radius, angle: angle, color: color, font: font, slantAngle: (System.nfloat)(angle + slantCorrection));
            thetaI += direction * arcs[i] / 2;
        }
    }

    nfloat chordToArc(nfloat chord, nfloat radius)
    {
        return (nfloat)(2 * Math.Asin(chord / (2 * radius)));
    }

    void centre(String str, CGContext context, nfloat radius, nfloat angle, UIColor color, UIFont font, nfloat slantAngle)
    {
        //var attributes = [NSForegroundColorAttributeName: color,
        //NSFontAttributeName: font]

        context.SaveState();
        //    // Undo the inversion of the Y-axis (or the text goes backwards!)
        context.ScaleCTM(1, -1);
        // Move the origin to the centre of the text (negating the y-axis manually)
        context.TranslateCTM((System.nfloat)(radius * Math.Cos(angle)), (System.nfloat)(-(radius * Math.Sin(angle))));
        // Rotate the coordinate system
        context.RotateCTM(-slantAngle);
        // Calculate the width of the text
        var offset = str.Length;
        // Move the origin by half the size of the text

        //CGContextTranslateCTM(context, -offset.width / 2, -offset.height / 2)
        context.TranslateCTM(-20 / 2, 20 / 2); // Move the origin to the centre of the text (negating the y-axis manually)
        // Draw the text
        str.DrawString(new CGPoint(x: 0, y: 0), font);
        // Restore the context
        context.RestoreState();
    }
}

一些 cmets 显示原始行,它可能没有正确翻译...它对我来说只显示黑色视图

【问题讨论】:

    标签: xamarin xamarin.ios cgcontext


    【解决方案1】:

    将swift代码转换为C#时有几个错误,我在下面的代码sn-p中更正了它们。它是黑色的原因是您没有为文本设置颜色。您可以改用NSString.DrawString 来实现。

    应该是这样的:

            public override void Draw(CoreGraphics.CGRect rect)
            {
                base.Draw(rect);
                this.BackgroundColor = UIColor.Clear;
                var context = UIGraphics.GetCurrentContext();
                var size = this.Bounds.Size;
    
                context.TranslateCTM(size.Width / 2, size.Height / 2);
                context.ScaleCTM(1, -1);
    
    
                CentreArcPerpendicular(str: "Hello round world", context: context, radius: 100, angle: 0, color: UIColor.Red, font: UIFont.SystemFontOfSize(16), clockwise: true);
                CentreArcPerpendicular(str: "Anticlockwise", context: context, radius: 100, angle: (System.nfloat)(-Math.PI / 2), color: UIColor.Red, font: UIFont.SystemFontOfSize(16), clockwise: false);
                centre(str: "Hello flat world", context: context, radius: 0, angle: 0, color: UIColor.Yellow, font: UIFont.SystemFontOfSize(16), slantAngle: (System.nfloat)(Math.PI / 4));
            }
    
            void CentreArcPerpendicular(String str, CGContext context, nfloat radius, nfloat angle, UIColor color, UIFont font, bool clockwise)
            {
                var l = str.Length;
                char[] characters = str.ToCharArray();
                nfloat[] arcs = new nfloat[l];
                nfloat totalArc = 0;
    
                for (int i = 0; i < l; i++)
                {
    
                    //Get the Size of the Char(Transfer to string to get the width)
                    NSString s = new NSString(Char.ToString(characters[i]));
                    CGSize size = s.GetSizeUsingAttributes(new UIStringAttributes(new NSDictionary(UIStringAttributeKey.Font, font)));
    
                    arcs[i] = chordToArc(size.Width, radius);
    
                    totalArc += arcs[i];
    
                }
    
                var direction = clockwise ? -1 : 1;
                var slantCorrection = clockwise ? -Math.PI / 2 : Math.PI / 2 ; //You lose the /2
    
                var thetaI = angle - direction * totalArc / 2;
    
    
                for (int i = 0; i < l; i++)
                {
                    thetaI += direction * arcs[i] / 2;
                    centre(str: characters[i].ToString(), context: context, radius: radius, angle: thetaI, color: color, font: font, slantAngle: (System.nfloat)(thetaI + slantCorrection)); // USe thetaI not angle !
                    thetaI += direction * arcs[i] / 2;
                }
            }
    
            nfloat chordToArc(nfloat chord, nfloat radius)
            {
                return (nfloat)(2 * Math.Asin(chord / (2 * radius)));
            }
    
            void centre(String str, CGContext context, nfloat radius, nfloat angle, UIColor color, UIFont font, nfloat slantAngle)
            {
                // Set the text attributes
                UIStringAttributes attribute = new UIStringAttributes()
                {
                    Font = font,
                    ForegroundColor = color
                };
    
                NSString s = new NSString(str);
    
                // Save the context
                context.SaveState();
                // Undo the inversion of the Y-axis (or the text goes backwards!)
                context.ScaleCTM(1, -1);
                // Move the origin to the centre of the text (negating the y-axis manually)
                context.TranslateCTM((System.nfloat)(radius * Math.Cos(angle)), (System.nfloat)(-(radius * Math.Sin(angle))));
                // Rotate the coordinate system
                context.RotateCTM(-slantAngle);
                // Calculate the width of the text
                var offset = s.GetSizeUsingAttributes(attribute);
                // Move the origin by half the size of the text
                context.TranslateCTM(-offset.Width / 2, -offset.Height / 2); // Move the origin to the centre of the text (negating the y-axis manually)
    
                // Draw the text
                s.DrawString(new CGPoint(0, 0), attribute);//use NSString.DrawString, then it can add attribute parameter.
                // Restore the context
                context.RestoreState();
            }
    

    它可以像这样正常工作:

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多