【问题标题】:how do I draw an arrow onto my view?如何在视图上绘制箭头?
【发布时间】:2011-04-25 22:43:58
【问题描述】:

您好,提前感谢您的任何回复。 我想在我的 UIView 上画一个宽大的箭头,它有浅绿色到深绿色的阴影。 我一直在查看 CGContextRef、CGPathRef 和 UIBezierPath 的文档,但我只是越来越困惑。 有人可以帮我解决这个问题吗?谢谢!

【问题讨论】:

  • 似乎没有太多(任何?)特定于 UIBezierPath 的示例代码,但您可以查看 NSBezierPath 的示例代码,可可等效项,以帮助您入门。
  • 我应该补充一点:它不会完全相同相同,但我认为相似性足以作为入口点。
  • 我明白了。我对其进行了一些研究,但我似乎可以正确声明它,因为它在构建时无法识别 NSBezierPath。我会继续尝试,谢谢!
  • NSBezierPath 在 iOS 上不可用; UIBezierPath 是它的 Cocoa-Touch 版本。它们非常相似;很多方法都是一样的。 NSBezierPath 有很多示例代码和教程材料,因此您可以制作一个测试 Cocoa (Mac OS X) 应用程序,使用 NSBezierPath,然后将您的新知识转移到在 iOS 上使用 UIBezierPath

标签: objective-c xcode drawing cgcontext


【解决方案1】:

问题很老,但我很高兴与您分享一些我希望有用的代码 - Swift 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)

以后我会为派克位置添加偏移量。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多