Xamarin.iOS 図形(直線)の描画

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

1 はじめに

Xamarin.iOSによる図形(直線)の描画についてです。

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

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

2 グラフィックコンテキストの取得

コンテキストの取得は、下記のパターンとなります。

partial class MyView : UIView {
    public MyView(IntPtr handle) : base(handle) {}

    // UIViewのDrawメソッドをオーバーライドする
    public override void Draw(CGRect rect) {
         base.Draw(rect);
        // グラフィックコンテキストの取得
         using(var context = UIGraphics.GetCurrentContext()) {

              //CGContext context を使用した描画の処理をここに記述

         }
    }
}

3 線の描画

線の描画に際して指定できる項目は、色、幅、パターン、そして、線の始まりと終わりの形状、合わせて、折れ線を書いた際の曲り形状です。

(1) 色

線の色は、SetStrokeColor()を使用して、コンテキストにCGColorをセットします。 また、CGColorの代わりに、R,G,B,Aで指定することも可能です、RGBは0~255 Aは0~1の値を指定します。

context.SetStrokeColor(UIColor.Black.CGColor);// 線を黒色にする
//context.SetStrokeColor(0,255,0,1.0f);// 線を緑色にする

各所で公開されてりるサンプルには、SetStrokeColorWithColorが使用されているものもありますが、こちらは、旧メソッドであり、利用が推奨されていません。

Application developers should use CGContext.SetStrokeColor(CGColor) rather than this obsolete method.

(2) 幅

線の幅は、SetLineWidthにポイント数を指定します。

context.SetLineWidth(15);//線の太さ 15pt

(3) パターン

線のパターンは、SetLineDashにパターンを指定します。 下記の例では、パターンが、2ポイント描画、2ポイント空白の連続なので、結果的に点線となります。

var dash = new nfloat[] { 2, 2 };//パターン ■■□□■■□□
context.SetLineDash(0, dash, dash.Length);

(4) 直線

直線は、始点と終点を指定してStrokePath()で描画します。

context.MoveTo(x, y);  // 始点
context.AddLineToPoint(x+80,y+80); // 終点
context.StrokePath(); // 描画

(5) 折れ線

直線と同じ書き方で、AddLineToPointを複数指定すると、その線は繋がって描画され、結果的に折れ線となります。 また、StrokePath()の前に、ClosePath()が入ると、折れ線は閉じた図形になります。

context.MoveTo(x, y);  // 始点
context.AddLineToPoint(x + 80, y + 80); // 経由点
context.AddLineToPoint(x + 140, y + 40); // 終点
context.ClosePath(); // 折れ線を閉じる
context.StrokePath(); // 描画

(6) 始点終点の形状

SetLineCap()によって、線をh描画する際に、始点と終点の形状が指定可能です。 形状は、四角、丸、ブッチの3種類が指定できます。

context.SetLineCap(CGLineCap.Butt);//ラインキャップ(ブッチ)

(7) 接続部の形状

折れ線を描画する場合は、その折れた部分の形状を指定できます。 形状は、斜め継、丸、べべルの3種類が指定できます。

 context.SetLineJoin(CGLineJoin.Miter);//接続部形状(斜め継ぎ)

4 サンプル

一通りの指定をサンプルにしてみました。

DrawLine001

public override void Draw(CGRect rect) {
    using (var context = UIGraphics.GetCurrentContext()) {

        //直線(ライン端がブッチで黒色の線)
        var x = 20;
        var y = 40;
        context.SetLineWidth(15);//線の太さ 15pt
        context.SetStrokeColor(UIColor.Black.CGColor);// 線を黒色にする(SetStrokeColorWithColorは、旧メソッド)
        context.SetLineCap(CGLineCap.Butt);//ラインキャップ(ブッチ)四角と比べて頂点に四角を描画しない分短くなる
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x+80,y+80); // 終点
        context.StrokePath(); // 描画

        //直線(ライン端が丸で青色の線)
        x += 80;//右へずらす
        context.SetStrokeColor(UIColor.Blue.CGColor);// 線を青色にする
        context.SetLineCap(CGLineCap.Round);//ラインキャップ(丸)
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x+80,y+80); // 終点
        context.StrokePath(); // 描画

        //直線(ライン端が四角で緑色の線)
        x += 80;//右へずらす
        context.SetStrokeColor(UIColor.Green.CGColor);// 線を緑色にする
        context.SetLineCap(CGLineCap.Square);//ラインキャップ(四角)
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.StrokePath(); // 描画

        //折れ線(継ぎ目が斜め継ぎで赤色の折れ線)
        x = 20;
        y = 130;
        context.SetLineWidth(20);//線の太さ 20pt
        context.SetStrokeColor(UIColor.Red.CGColor);// 線を赤色にする
        context.SetLineJoin(CGLineJoin.Miter);//接続部形状(斜め継ぎ)
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x+80,y+80); // 終点
        context.AddLineToPoint(x+140,y+40); // 終点
        context.StrokePath(); // 描画

        //折れ線(継ぎ目がべベルでオレンジ色の折れ線)
        y += 80;//下へずらす
        context.SetStrokeColor(UIColor.Orange.CGColor);// 線をオレンジ色にする
        context.SetLineJoin(CGLineJoin.Bevel);//接続部形状(べベル)
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.AddLineToPoint(x + 140, y + 40); // 終点
        context.StrokePath(); // 描画

        //折れ線(継ぎ目が丸で茶色の折れ線)
        y += 80;//下へずらす
        context.SetStrokeColor(UIColor.Brown.CGColor);// 線を茶色にする
        context.SetLineJoin(CGLineJoin.Round);//接続部形状(丸)
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.AddLineToPoint(x + 140, y + 40); // 終点
        context.StrokePath(); // 描画

        //折れ線(紫色の閉じられた折れ線)
        y += 80;//下へずらす
        context.SetStrokeColor(UIColor.Magenta.CGColor);// 線を紫色にする
        context.SetLineJoin(CGLineJoin.Miter);//接続部形状(斜め継ぎ)
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.AddLineToPoint(x + 140, y + 40); // 終点
        context.ClosePath(); // 折れ線を閉じる
        context.StrokePath(); // 描画

        //直線(2ドットの点線)
        x = 20;
        y = 480;
        context.SetLineWidth(1);//線の太さ 1pt
        context.SetStrokeColor(UIColor.Black.CGColor);// 線を黒色にする
        var dash = new nfloat[] { 2, 2 };//パターン ■■□□■■□□
        context.SetLineDash(0, dash, dash.Length);
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.StrokePath(); // 描画

        //直線(10ドット(空白4ドット)の破線)
        x += 80;//右へずらす
        context.SetStrokeColor(UIColor.Black.CGColor);// 線を黒色にする
        dash = new nfloat[] { 10, 4 };//パターン ■■■■■■■■■■□□□□
        context.SetLineDash(0,dash,dash.Length);
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.StrokePath(); // 描画

        //直線(10ドットと5ドットの一点破線)
        x += 80;//右へずらす
        context.SetStrokeColor(UIColor.Black.CGColor);// 線を黒色にする
        dash = new nfloat[] { 10, 4, 5, 4 };//パターン ■■■■■■■■■■□□□□■■■■■□□□□
        context.SetLineDash(0, dash, dash.Length);
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.StrokePath(); // 描画

        //直線(10ドットと5ドットの一点破線)線の太さ2
        x += 80;//右へずらす
        context.SetLineWidth(2);//線の太さ 2pt
        context.SetStrokeColor(UIColor.Black.CGColor);// 線を黒色にする
        dash = new nfloat[] { 10, 4, 5, 4 };//パターン ■■■■■■■■■■□□□□■■■■■□□□□
        context.SetLineDash(0, dash, dash.Length);
        context.MoveTo(x, y);  // 始点
        context.AddLineToPoint(x + 80, y + 80); // 終点
        context.StrokePath(); // 描画
     }
}

5 まとめ

今回は、CGContextを使用した直線の描画についてまとめてみました。 このDrawメソッドをオーバーライドする手法は、Xamarin.FormsでBoxViewなどをレンダラーで拡張するときにも、そのまま応用可能です。

6 参考リンク

Xamarin Developers Core Graphics
Xamarin Developers UIKit.UIGraphics Class
Xamarin記事一覧(SAPPOROWORKSの覚書)