本文介绍了如何在 Xamarin iOS 中绘制文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我已关注 Xamarin 网站上的

使用 NSMutableParagraphStyle 和 NSString.DrawString

var context = UIGraphics.GetCurrentContext();CGRect textRect = new CGRect(0.0f, 0.0f, 200.0f, 100.0f);{var textContent = "你好\n你好吗?\n真诚的\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();}

I would like to draw text at a given point (x, y) in the Draw method of a custom View.

I have followed this sample from the Xamarin site.

This is the View I created:

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);
        }
    }
}

The problem is that the DrawText method only works OK once. The first time you call it the text is drawn, but it doesn't work on successive calls (it draws nothing, or what it draws isn't visible).

What am I doing wrong?

解决方案

So there are two basic things that are wrong with your code.

  • You are performing a ScaleCTM and a TranslateCTM each time you call DrawText
  • You do not take into account that when you CTLine.Draw, the "cursor" is moved to the end of that text.

So, call ScaleCTM to flipped the whole thing so the text gets draw left2right, then call DrawText and translate to where you want to paint the text and then translate back to where you started so the next time you are at the same point.

Example Draw override:

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);
}

Results in:

Using NSMutableParagraphStyle and 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();
}

这篇关于如何在 Xamarin iOS 中绘制文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:27