Xamarin.iOS 文字列の描画

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

今回は、Xamarin.iOSの文字列描画です。 Xamarin.iOSの「NSString」には、DrawString()というメソッドがあり、簡単に文字列が描画できます。

サンプルは、UIViewのDraw()への描画になっています。Xamarin.iOSでのUIViewのサブクラス化がピンとこない場合は、下記をご参照ください。

Xamarin.iOS テンプレート(Single View App)

なお、図形(直線・矩形・円)の描画に使用していた「グラフィックコンテキスト」は、ここでは必要ありません。

2 フォント

DrawString()で文字列を描画する際、最低限フォン ト(UIFont)の指定が必要ですが、このフォントを簡単に取得する方法として下記の4種類があります。

  • UIFont.SystemFontOfSize(nfroat size) //システムフォント
  • UIFont.BoldSystemFontOfSize(nfroat size) //ボールド
  • UIFont.ItalicSystemFontOfSize(nfroat size) //イタリック
  • UIFont.FromName(string name,nfroat size) //フォント名で指定

色々なフォントを取得して文字列を描画してみたサンプルは、次のようになります。

public override void Draw(CGRect rect) {
    base.Draw(rect);

    var str = new NSString("Developers.IO");
    const int size = 30; //フォントサイズ(30pt)
    const int x = 40;
    var y = 50;

    //システムフォントで描画する
    str.DrawString(new CGPoint(x, y += 50), UIFont.SystemFontOfSize(size));

    //ボールドフォントで描画する
    str.DrawString(new CGPoint(x, y += 50), UIFont.BoldSystemFontOfSize(size));

    //イタリックフォントで描画する
    str.DrawString(new CGPoint(x, y += 50), UIFont.ItalicSystemFontOfSize(size));

    //Helvetica-Boldフォントで描画する
    str.DrawString(new CGPoint(x, y += 50), UIFont.FromName("Helvetica-Bold", size));
}

iOSDrawString001

フォント名は、UIFont.FontNamesForFamilyName(family)でフォントファミリーごとに列挙が可能です。また、フォントファミリーは、UIFont.FamilyNamesで列挙できます。 下記のコードは、iOS端末で利用可能なフォントをすべて列挙したものです。

public override void Draw(CGRect rect) {
    base.Draw(rect);

    const int size = 10; //フォントのサイズ(12pt)
    const int x = 20;
    const int h = 15;
    var y = 0;

    //フォントファミリーを列挙
    foreach (var family in UIFont.FamilyNames) {
        //フォントファミリー名の表示
         ((NSString)("[Family] " + family)).DrawString(new CGPoint(x, y += h), UIFont.SystemFontOfSize(size));

        //フォントファミリに属するフォントを列挙
        foreach (var n in UIFont.FontNamesForFamilyName(family)) {

            //当該フォントを使用してフォント名を表示
           ((NSString)n).DrawString(new CGPoint(x + 20, y += h), UIFont.FromName(n, size));
        }
    }
}

iOSDrawString002

フォントのサンプルとして、最後にiPhoneに標準でインストールされている日本語フォントである「ヒラギノ」のゴシック体と明朝体を表示してみます。

public override void Draw(CGRect rect) {
    base.Draw(rect);

    var x = 20;
    var y = 20;
    var ar = new List<String>{
        "Hiragino Kaku Gothic ProN W3",
        "Hiragino Kaku Gothic ProN W6",
         "Hiragino Mincho ProN W3",
        "Hiragino Mincho ProN W6"
    };
    foreach (var font in ar.Select(n => UIFont.FromName(n, 25))) {
        ((NSString)"クラスメソッド株式会社").DrawString(new CGPoint(x, y += 35), font);
    }
}

iOSDrawString003

3 文字列属性

NSStringのDrawString()には、先のようにフォントだけでなく、属性(UIStringAttributes)を指定してできるものもあります。

public override void Draw(CGRect rect) {
    base.Draw(rect);

    const int x = 20;
    const int y = 50;

    //属性の生成
    var attr = new UIStringAttributes {
        ForegroundColor = UIColor.White,//文字色(白色)
        BackgroundColor = UIColor.Orange,//背景色(オレンジ色)
        Font = UIFont.FromName("Courier", 35f),//フォント Courier 35ポイント
        UnderlineColor = UIColor.Red,//下線色( 赤色)
        UnderlineStyle = NSUnderlineStyle.Double//下線スタイル(2重)
    };
    //表示位置と属性を指定して文字列を表示する
    ((NSString)"Developers.IO").DrawString(new CGPoint(x, y), attr);
}

iOSDrawString004

指定可能な属性には、下記のようなものが指定可能です。

  • BackgroundColor 文字の背景色
  • BaselineOffset ベースラインからのオフセット
  • Font フォント属性
  • ForegroundColor 文字の色
  • KerningAdjustment カーニング
  • Ligature リガチャをするか否か
  • ParagraphStyle 段落の書式
  • Shadow //影
  • StrikethroughColor
  • StrikethroughStyle
  • StrokeColor 枠線の色
  • StrokeWidth 枠線の幅
  • UnderlineColor 下線の色
  • UnderlineStyle 下線のスタイル

詳しくは下記のリンクをご参照ください。

Xamarin Devepolers [UIKit.UIStringAttributeKey Class]

4 範囲を指定した文字列描画

NSStringのWeakDrawString()を使用すると、矩形内に文字列を描画できます。 第2パラメータに必要とされる属性は、NSDirectoryですが、こちらは、UIStringAttributesを生成して、そのパラメータ(Dictionary)を使用できます。

public override void Draw(CGRect rect) {
    base.Draw(rect);
            
    //NSStringの生成
    var str = new NSString("智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟つた時、詩が生れて、畫が出來る。人の世を作ったものは神でもなければ鬼でもない。矢張り向ふ三軒兩隣りにちらちらする唯の人である。唯の人が作つた人の世が住みにくいからとて、越す國はあるまい。あれば人でなしの國へ行く許りだ。人でなしの國は人の世よりも猶住みにくからう。");
    //属性(フォントのみ指定)の生成
    var attr = new UIStringAttributes {
        Font = UIFont.SystemFontOfSize(15)
    };
    //指定範囲の中に描画(オーバした部分は、カットされる)
    str.WeakDrawString(new CGRect(40, 40, 240, 240), attr.Dictionary);
}

iOSDrawString005

5 文字サイズの取得

文字列を描画する面積を取得したい場合があります。 NSStringのStringSize()で取得が可能ですが、描画面積は、当然フォントのサイズなどによって変化しますので、その指定が必要になります。

public override void Draw(CGRect rect) {
    base.Draw(rect);

    const int x = 10;
    var y = 40;
    var pt = 10;
    Disp("10ポイントの文字列", x, y += pt + 15, pt);
    pt = 15;
    Disp("15ポイントの文字列", x, y += pt + 15, pt);
    pt = 20;
    Disp("20ポイントの文字列", x, y += pt + 15, pt);
    pt = 25;
    Disp("25ポイントの文字列", x, y += pt + 15, pt);
    pt = 36;
    Disp("36ポイントの文字列", x, y += pt + 15, pt);
}
       
//文字列と座標及びフォントサイズを指定して描画する
static void Disp(String str, int x, int y,int fontSize) {
    //指定されたサイズでシステムフォントを生成する
    var font = UIFont.SystemFontOfSize(fontSize);
    //文字列のサイズの取得
    var size = ((NSString) str).StringSize(font);
    //サイズの描画
    var s = string.Format("size:{0}×{1}", size.Width, size.Height);
    ((NSString)s).DrawString(new CGPoint(x, y), UIFont.SystemFontOfSize(12));
    //文字列の描画
    ((NSString)str).DrawString(new CGPoint(x, y+14), font);
}

iOSDrawString006

6 まとめ

今回は、文字列の描画についてまとめてみました。 最初に紹介した通り、文字列の描画では、CGContext(クラフィックコンテキスト)を使用しませんが、記述はDrawメソッド内になると思いまます。 なお、こちらもXamarin.FormsでBoxViewなどのレンダラー拡張で、必要になるかもしれません。

7 参考リンク


Xamarin.Formsで明朝系フォントを使用する
iOS 7:フォントリスト
Xamarin Developers [Style Text]
Xamarin.iOS「図形(直線)の描画」
Xamarin記事一覧(SAPPOROWORKSの覚書)