2017-10-17 99 views
0

我已经找到了答案在下面的链接绘制沿圆形路径文本: Draw text along circular path in Swift for iOS在xamarin 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(); 
    } 
} 

一些评论为原始的线条,它可能无法正确翻译......它显示了我刚刚黑观点

回答

1

是有几次失误,当你转换SWIFT代码到C#,我已经改正他们在下面的代码片段。黑色的原因是你没有设置文字的颜色。您可以使用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(); 
     } 

它工作正常,像这样:

enter image description here