2011-04-25 144 views
1

您好,並提前感謝您的任何答覆。 我想在我的UIView上繪製一個很寬的箭頭,它有淺綠色到深綠色的陰影。 我一直在尋找CGContextRef,CGPathRef和UIBezierPath的文檔,但我只是越來越困惑。 有人可以幫助我這個。謝謝!如何在我的視圖上繪製箭頭?

+0

似乎沒有很多(任何?)特定於「UIBezierPath」的示例代碼,但您可以查看「NSBezierPath」的示例代碼,Cocoa等價物,以幫助您入門。 – 2011-04-26 00:48:05

+0

我應該補充說:它不會是完全相同的,但我認爲相似性對於一個入口點是足夠的。 – 2011-04-26 01:26:35

+0

我明白了。我仔細研究了一下,但我似乎正確地聲明瞭它,因爲它在構建時不承認NSBezierPath。我會繼續嘗試,謝謝! – serge2487 2011-04-26 02:55:39

回答

0

早在2004年,我寫了a blog post about drawing nice MetaPost-like arrows using NSBezierPath,你可能想看看。

根據需要,它應該很容易適應CoreGraphics或UIBezierPath

+0

只是一個關於你的例子的問題。你說這只是繪製三角形並根據線的方向旋轉它的問題,但如果你正在處理曲線,如何確定線的方向?你是否抽樣瞭解最後得出的點或知道什麼?謝謝。 – SpaceDog 2011-06-12 21:57:28

+0

@數字機器人:如果你閱讀這篇文章,它實際上評論說Bézier曲線的控制多邊形與其端點處的曲線相切 - 也就是說,你可以使用端點和上一個(或下一個)控制之間的連線點。如果曲線退化(例如重疊的控制點),唯一不起作用的是,如果要真正有效,您可能需要處理這種情況。 – alastair 2011-06-22 08:28:22

+0

啊......我誤解了。謝謝。 – SpaceDog 2011-06-22 15:02:15

0

問題是舊的,但我很高興與大家分享您一些代碼,希望有用 - 雨燕2.3兼容 -

public extension UIView { 

    public enum PeakSide: Int { 
     case Top 
     case Left 
     case Right 
     case Bottom 
    } 

    public func addPikeOnView(side side: PeakSide, size: CGFloat = 10.0) { 
     self.layoutIfNeeded() 
     let peakLayer = CAShapeLayer() 
     var path: CGPathRef? 
     switch side { 
     case .Top: 
      path = self.makePeakPathWithRect(self.bounds, topSize: size, rightSize: 0.0, bottomSize: 0.0, leftSize: 0.0) 
     case .Left: 
      path = self.makePeakPathWithRect(self.bounds, topSize: 0.0, rightSize: 0.0, bottomSize: 0.0, leftSize: size) 
     case .Right: 
      path = self.makePeakPathWithRect(self.bounds, topSize: 0.0, rightSize: size, bottomSize: 0.0, leftSize: 0.0) 
     case .Bottom: 
      path = self.makePeakPathWithRect(self.bounds, topSize: 0.0, rightSize: 0.0, bottomSize: size, leftSize: 0.0) 
     } 
     peakLayer.path = path 
     let color = (self.backgroundColor ?? .clearColor()).CGColor 
     peakLayer.fillColor = color 
     peakLayer.strokeColor = color 
     peakLayer.lineWidth = 1 
     peakLayer.position = CGPoint.zero 
     self.layer.insertSublayer(peakLayer, atIndex: 0) 
    } 


    func makePeakPathWithRect(rect: CGRect, topSize ts: CGFloat, rightSize rs: CGFloat, bottomSize bs: CGFloat, leftSize ls: CGFloat) -> CGPathRef { 
     //      P3 
     //     / \ 
     //  P1 -------- P2  P4 -------- P5 
     //  |        | 
     //  |        | 
     //  P16       P6 
     // /        \ 
     // P15         P7 
     //  \        /
     //  P14       P8 
     //  |        | 
     //  |        | 
     //  P13 ------ P12 P10 -------- P9 
     //     \ /
     //      P11 

     let centerX = rect.width/2 
     let centerY = rect.height/2 
     var h: CGFloat = 0 
     let path = CGPathCreateMutable() 
     var points: [CGPoint] = [] 
     // P1 
     points.append(CGPointMake(rect.origin.x, rect.origin.y)) 
     // Points for top side 
     if ts > 0 { 
      h = ts * sqrt(3.0)/2 
      let x = rect.origin.x + centerX 
      let y = rect.origin.y 
      points.append(CGPointMake(x - ts, y)) 
      points.append(CGPointMake(x, y - h)) 
      points.append(CGPointMake(x + ts, y)) 
     } 

     // P5 
     points.append(CGPointMake(rect.origin.x + rect.width, rect.origin.y)) 
     // Points for right side 
     if rs > 0 { 
      h = rs * sqrt(3.0)/2 
      let x = rect.origin.x + rect.width 
      let y = rect.origin.y + centerY 
      points.append(CGPointMake(x, y - rs)) 
      points.append(CGPointMake(x + h, y)) 
      points.append(CGPointMake(x, y + rs)) 
     } 

     // P9 
     points.append(CGPointMake(rect.origin.x + rect.width, rect.origin.y + rect.height)) 
     // Point for bottom side 
     if bs > 0 { 
      h = bs * sqrt(3.0)/2 
      let x = rect.origin.x + centerX 
      let y = rect.origin.y + rect.height 
      points.append(CGPointMake(x + bs, y)) 
      points.append(CGPointMake(x, y + h)) 
      points.append(CGPointMake(x - bs, y)) 
     } 

     // P13 
     points.append(CGPointMake(rect.origin.x, rect.origin.y + rect.height)) 
     // Point for left side 
     if ls > 0 { 
      h = ls * sqrt(3.0)/2 
      let x = rect.origin.x 
      let y = rect.origin.y + centerY 
      points.append(CGPointMake(x, y + ls)) 
      points.append(CGPointMake(x - h, y)) 
      points.append(CGPointMake(x, y - ls)) 
     } 

     let startPoint = points.removeFirst() 
     self.startPath(path: path, onPoint: startPoint) 
     for point in points { 
      self.addPoint(point, toPath: path) 
     } 
     self.addPoint(startPoint, toPath: path) 
     return path 
    } 

    private func startPath(path path: CGMutablePath, onPoint point: CGPoint) { 
     CGPathMoveToPoint(path, nil, point.x, point.y) 
    } 

    private func addPoint(point: CGPoint, toPath path: CGMutablePath) { 
     CGPathAddLineToPoint(path, nil, point.x, point.y) 
    } 

} 

通過這種方式,你可以把這種對每一種觀點:

let view = UIView(frame: frame) 
view.addPikeOnView(side: .Top) 

未來我會爲派克位置添加抵消。

  • 是的,名字肯定是可以改進的!