2013-03-21 216 views
2

我有一些Xamarin.iOS CoreGraphics代碼,它在幾個不同角度的白色線條的末端繪製紅色三角形。爲什麼CoreGraphics FillPath沒有填充指定路徑

enter image description here

我想已經填充了而不是被渲染爲輪廓,但是當我用,而不是StrokePath的圖形上下文命令FillPath()()的紅色三角形不會出現紅色的三角形。

enter image description here

這裏的DrawArrowHead代碼(由線上的每個單獨的線之後繪製代碼稱爲繪製)。

private void DrawArrowHead(PointF[] line, int size) 
{ 
    // Create the arrowhead and the lines from individual arrowhead points 
    PointF[] arrowhead = new PointF[] { 
     new PointF(0.0f - size, 0.0f), 
     new PointF(0.0f, 0.0f - size), 
     new PointF(0.0f + size, 0.0f) 
    }; 

    PointF[] line1 = new PointF[] {new PointF(arrowhead[0].X, arrowhead[0].Y), new PointF(arrowhead[1].X, arrowhead[1].Y)}; 
    PointF[] line2 = new PointF[] {new PointF(arrowhead[1].X, arrowhead[1].Y), new PointF(arrowhead[2].X, arrowhead[2].Y)}; 
    PointF[] line3 = new PointF[] {new PointF(arrowhead[2].X, arrowhead[2].Y), new PointF(arrowhead[0].X, arrowhead[0].Y)}; 

    // Begin drawing the arrowhead 
    gctx.SaveState(); 

    UIColor.Red.SetStroke(); 
    gctx.SetFillColor(UIColor.Red.CGColor); 

    gctx.BeginPath(); 

    double angleInRadians = Math.Atan2 (line[0].Y - line[1].Y, line[0].X -line[1].X); 

    gctx.TranslateCTM(line[1].X, line[1].Y); 
    gctx.RotateCTM((float)(angleInRadians - Math.PI/2)); 

    path.AddLines(line1); 
    path.AddLines(line2); 
    path.AddLines(line3); 

    path.CloseSubpath(); 

    gctx.AddPath(path); 

    gctx.StrokePath(); 

    gctx.RestoreState(); 
} 

當我更換gctx.StrokePath()與gctx.FillPath()我得到的白線,但沒有箭頭。

enter image description here

當我更換gctx.StrokePath()與gctx.DrawPath(CGPathDrawingMode.FillStroke)我得到的紅色三角形,但是他們沒有填寫。

enter image description here

我我確定這很簡單,我錯過了。提前致謝。

Update - 03.22.13 

原來@ poupou的答案是正確的,但通過我的一些其他編碼複合「誤解」,沒有解決我的問題的時候了。但是,由於它指出我正朝着解決方案的正確方向,我正在接受他的答案。

我第一次學會了如何通過Mike Bluestein的優秀Drawing with CoreGraphics in MonoTouch文章使用CoreGraphics。然而,一點知識是一件危險的事情,當我開始將這些概念應用到我自己的工作中時,我不經意地混合了圖形上下文和路徑方法。

很多谷歌上搜索,閱讀和審查其他民族CoreGraphics中的源代碼(道具尼娜Vyedin和Xamarin的布萊恩Costanich爲他們繪製sample)後,我想出了一個方法DrawArrowhead的作品。

private void DrawArrowHead(PointF[] line, int size) 
{ 
    gctx.SaveState(); 
    UIColor.Red.SetStroke(); 
    UIColor.Red.SetFill(); 
    double angleInRadians = Math.Atan2 (line[0].Y - line[1].Y, line[0].X -line[1].X); 

    gctx.BeginPath(); 
    gctx.TranslateCTM(line[1].X, line[1].Y); 
    gctx.RotateCTM((float)(angleInRadians - Math.PI/2)); 

    PointF[] arrowhead = new PointF[] { 
     new PointF (0.0f - arrowHeadSize, 0.0f), 
     new PointF (0.0f, 0.0f - arrowHeadSize), 
     new PointF (0.0f + arrowHeadSize, 0.0f) 
    }; 

    gctx.MoveTo(arrowhead[0].X, arrowhead[0].Y); 
    gctx.AddLineToPoint(arrowhead[1].X, arrowhead[1].Y); 
    gctx.AddLineToPoint(arrowhead[2].X, arrowhead[2].Y); 

    gctx.ClosePath();     
    gctx.DrawPath(CGPathDrawingMode.FillStroke);         
    gctx.RestoreState(); 
} 

下面是最終結果。

enter image description here

注:我不得不移動DrawArrowHead碼出它的方法,然後進入我的UIView的繪製方法繪製的第二,第三,第四和第五行/箭頭組合時,爲了避免無效的上下文錯誤(你可以閱讀有關該類型的錯誤here)。

回答

1

調用上的CGPathpath.CloseSubpath();是不相同的一個CGContext(其中行程/填充將被完成)調用gctx.ClosePath();。你試過後面的嗎?

+0

使用gctx.FillPath()和gctx.DrawPath(CGPathDrawingMode.FillStroke)時,使用gctx.ClosePath()替換path.CloseSubpath()會得到相同的結果。但這是一個很好的建議。 – billmaya 2013-03-21 13:14:39

+0

path.CloseSubpath在可重用路徑上使用,gctx.ClosePath在繪製時從圖形上下文刷新的路徑上。 – billmaya 2013-03-22 09:41:59

+0

使用gctx。ClosePath是朝着正確方向邁出的一步。請參閱我原始問題中的Update - 03.22.13部分。 – billmaya 2013-03-22 12:30:59