この記事は公開されてから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));
}
フォント名は、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));
}
}
}
フォントのサンプルとして、最後に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);
}
}
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);
}
指定可能な属性には、下記のようなものが指定可能です。
- 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);
}
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);
}
6 まとめ
今回は、文字列の描画についてまとめてみました。 最初に紹介した通り、文字列の描画では、CGContext(クラフィックコンテキスト)を使用しませんが、記述はDrawメソッド内になると思いまます。 なお、こちらもXamarin.FormsでBoxViewなどのレンダラー拡張で、必要になるかもしれません。