创建向上箭头

Creating Upside Arrow

我正在尝试显示所选页面菜单的箭头。但是,我画的箭头并没有像我预期的那样显示出来。它需要起来

这是我的代码:

class ArrowView : UIView {

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override init(frame: CGRect) {
    super.init(frame: frame)
    self.backgroundColor = UIColor.clear
}

var rect: CGRect!
var arrorBackgroundColor: UIColor?

var midX: CGFloat { return rect.midX }
var midY: CGFloat { return rect.midY }
var maxX: CGFloat { return rect.maxX }
var maxY: CGFloat { return rect.maxY }

override func draw(_ rect: CGRect) {
    self.rect = rect

    let ctx = UIGraphicsGetCurrentContext()

    ctx?.beginPath()
    ctx?.move(to: CGPoint(x: 0, y: 0))

//        Old code which the arrow was down
//        ctx?.addQuadCurve(to: CGPoint(x:maxX * 0.2 , y: maxY * 0.2), control: CGPoint(x: maxX * 0.12, y: 0))
//        ctx?.addLine(to: CGPoint(x: midX - maxX * 0.05, y: maxY * 0.9))
//        ctx?.addQuadCurve(to: CGPoint(x: midX + maxX * 0.05, y: maxY * 0.9), control: CGPoint(x: midX, y: maxY))
//        ctx?.addLine(to: CGPoint(x: maxX * 0.8, y: maxY * 0.2))
//        ctx?.addQuadCurve(to: CGPoint(x: maxX, y: 0), control: CGPoint(x: maxX * 0.88, y: 0))

    ctx?.addLine(to: CGPoint(x: midX - maxX * 106.5, y: maxY * 65.5))
    ctx?.addLine(to: CGPoint(x: maxX * 128.5, y: maxY * 88.5))
    ctx?.addLine(to: CGPoint(x: 85.5, y: 88.5))
    ctx?.closePath()

    ctx?.setFillColor((arrorBackgroundColor?.cgColor)!)
    ctx?.fillPath();
}

}

进展如何

实际上我正在尝试自定义这个库:https://github.com/azurechen/ACTabScrollView

并尝试像这样归档:https://puu.sh/viWwc/35a6bddb0d.png

由于我是 UIBezierPath 的新手,任何帮助都将不胜感激。

我不明白你对 addLine(to:) 的调用中的常量,我认为 ArrowView 的实现不必要地奇怪。

您似乎对 midX/maxX/...感到困惑(或者我太笨了,现在无法理解)。 CGRect documentation 应该有帮助。

我认为 ArrowView 的原作者(来自您链接到的 github 项目)在设置箭头位置时以某种方式混淆了 boundsframe。哦,他还滥用了 draw(_:) 中的 rect 参数,参见 the docs。具体来说(强调我的):

rect
The portion of the view’s bounds that needs to be updated. The first time your view is drawn, this rectangle is typically the entire visible bounds of your view. However, during subsequent drawing operations, the rectangle may specify only part of your view.

此外,ACTabScrollView 似乎只是有时有效。在我浅薄的实验中,大部分时间它都会弄乱视图定位。

无论如何,要为向上箭头实现一个简单的 UIView,这个可行:

class ArrowView : UIView {
    var arrorBackgroundColor: UIColor = UIColor.red

    override func draw(_ rect: CGRect) {
        guard let ctx = UIGraphicsGetCurrentContext() else { return }

        // Sample to really fill the background before drawing the arrow.    
        ctx.setFillColor(UIColor.yellow.cgColor)
        ctx.fill(bounds)

        ctx.beginPath()
        ctx.move(to: CGPoint(x: 0, y: bounds.maxY))
        ctx.addLine(to: CGPoint(x: bounds.midX, y: bounds.minY))
        ctx.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
        ctx.addLine(to: CGPoint(x: 0, y: bounds.maxY))
        ctx.closePath()

        ctx.setFillColor(arrorBackgroundColor.cgColor)
        ctx.fillPath()
    }
}

核心是使用视图的bounds来计算坐标。

来自 the UIView docs:

The geometry of a view is defined by its frame, bounds, and center properties. The frame defines the origin and dimensions of the view in the coordinate system of its superview and is commonly used during layout to adjust the size or position of the view. The center property can be used to adjust the position of the view without changing its size. The bounds defines the internal dimensions of the view as it sees them and is used almost exclusively in custom drawing code. The size portion of the frame and bounds rectangles are coupled together so that changing the size of either rectangle updates the size of both.

我觉得 arrorBackgroundColor 真的应该叫 arrowColor(因为它被用作箭头的颜色)而且你可能还有另一个 属性 arrorBackgroundColor是为背景。我添加了两条线,以黄色填充背景作为示例。