c# - 如何在 Xamarin iOS 中绘制文本?

标签 c# ios .net xamarin xamarin.ios

我想在自定义 ViewDraw 方法中在给定点 (x, y) 绘制文本。

我已关注this sample来自 Xamarin 网站。

这是我创建的 View :

public class MyView : UIView
{
    public override void Draw(CGRect rect)
    {
        using (var context = UIGraphics.GetCurrentContext())
        {
            DrawText(context, "hello", 20, new CGPoint(0, 0));
            DrawText(context, "how are you", 20, new CGPoint(0, 40));
        }
    }

    private void DrawText(CGContext context, string text, int textHeight, CGPoint point)
    {
        var x = point.X;
        var y = point.Y + textHeight;

        context.TranslateCTM(x, y);

        context.ScaleCTM(1, -1);
        context.SetFillColor(UIColor.Red.CGColor);

        var attributedString = new NSAttributedString(text,
            new CTStringAttributes
            {
                ForegroundColorFromContext = true,
                Font = new CTFont("Arial", 16)
            });

        using (var textLine = new CTLine(attributedString))
        {
            textLine.Draw(context);
        }
    }
}

问题是 DrawText 方法只能正常运行一次。第一次调用它时,会绘制文本,但它在连续调用时不起作用(它不绘制任何内容,或者绘制的内容不可见)。

我做错了什么?

最佳答案

因此,您的代码有两个基本问题。

  • 每次调用 DrawText 时,您都会执行 ScaleCTMTranslateCTM
  • 您没有考虑到当您CTLine.Draw时,“光标”会移动到该文本的末尾。

因此,调用 ScaleCTM 翻转整个内容,以便文本从左到右绘制,然后调用 DrawText 并转换到您想要绘制文本的位置,然后 翻译回到您开始的位置,以便下次您处于同一点时。

绘制覆盖示例:

public override void Draw(CGRect rect)
{
    var context = UIGraphics.GetCurrentContext();
    context.ScaleCTM(1, -1); // you flipped the context, now you must use negative Y values to draw "into" the view

    var textHeight = new CTFont("Arial", 16).CapHeightMetric; // lets use the actaul height of the font captials.

    DrawText(context, "Hello", textHeight, 0, 0);
    DrawText(context, "How are you?", textHeight, 0, 20);
    DrawText(context, "Sincerely,", textHeight, 0, 40);
    DrawText(context, "StackOverflow,", textHeight, 0, 60);
}

void DrawText(CGContext context, string text, nfloat textHeight, nfloat x, nfloat y)
{
    context.TranslateCTM(-x, -(y + textHeight));
    context.SetFillColor(UIColor.Red.CGColor);

    var attributedString = new NSAttributedString(text,
        new CTStringAttributes
        {
            ForegroundColorFromContext = true,
            Font = new CTFont("Arial", 16)
        });

    CGRect sizeOfText;
    using (var textLine = new CTLine(attributedString))
    {
        textLine.Draw(context);
        sizeOfText = textLine.GetBounds(CTLineBoundsOptions.UseOpticalBounds);
    }
    // Reset the origin back to where is was
    context.TranslateCTM(x - sizeOfText.Width, y + sizeOfText.Height); 
}

结果:

enter image description here

使用 NSMutableParagraphStyle 和 NSString.DrawString

var context = UIGraphics.GetCurrentContext();
CGRect textRect = new CGRect(0.0f, 0.0f, 200.0f, 100.0f);
{
    var textContent = "Hello\nHow are you?\nSincerely,\nStackOverflow";
    UIColor.Red.SetFill();
    var textStyle = new NSMutableParagraphStyle ();
    textStyle.Alignment = UITextAlignment.Left;

    var textFontAttributes = new UIStringAttributes () {Font = UIFont.FromName("ArialMT", 16.0f), ForegroundColor = UIColor.Red, ParagraphStyle = textStyle};
    var textTextHeight = new NSString(textContent).GetBoundingRect(new CGSize(textRect.Width, nfloat.MaxValue), NSStringDrawingOptions.UsesLineFragmentOrigin, textFontAttributes, null).Height;
    context.SaveState();
    context.ClipToRect(textRect);
    new NSString(textContent).DrawString(new CGRect(textRect.GetMinX(), textRect.GetMinY() + (textRect.Height - textTextHeight) / 2.0f, textRect.Width, textTextHeight), UIFont.FromName("ArialMT", 16.0f), UILineBreakMode.WordWrap, UITextAlignment.Left);
    context.RestoreState();
}

关于c# - 如何在 Xamarin iOS 中绘制文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44400322/

相关文章:

android - 在 iPhone 和 Android 上流式传输的最佳音频文件格式是什么

.net - 关于如何将数据流式传输到服务器 .NET 的最佳实践

c# - 具有多个系列的 MS 图表上的工具提示标签错误

c# - 无法使用switch语句C#将常量值转换为 'bool'

C# OneDrive for Business/SharePoint : get server path from locally synced file

c# - 从该方法中获取变量调用方法的名称

c# - 将 EF CodeFirst 基类转换为继承类(使用 table-per-type)

ios - 供应配置文件不包括应用程序标识符和钥匙串(keychain)访问组权利

ios - SKReferenceNode 缩放后 Swift 碰撞不起作用

c# - System.IO.FileNotFoundException : The network path was not found. 在 Windows 7 上使用 DirectoryEntry 对象时出现异常