2011-04-25 44 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) 

未来我会为派克位置添加抵消。

  • 是的,名字肯定是可以改进的!
相关问题