创建上行箭头

时间:2017-04-12 05:06:33

标签: swift3 uibezierpath uigraphicscontext

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

这是我的代码:

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();
}

}

这里是怎么回事

enter image description here

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

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

由于我是UIBezierPath的初学者,所以我们非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我不理解您对addLine(to:)的调用中的常量,我认为ArrowView的实现不必要地很奇怪。

你似乎对midX / maxX / ...感到困惑(或者我现在太过密集而无法正确使用它)。 CGRect documentation应该会有所帮助。

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

  

<强> RECT
  视图边界的一部分需要更新。该   第一次绘制视图时,此矩形通常是整个   您视图的可见边界。 但是,在后续绘图中   在操作中,矩形可以仅指定视图的一部分。

此外,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

  

视图的几何形状由其框架,边界和中心定义   属性。框架定义了视图的原点和尺寸   其超视图的坐标系统,常用于   布局以调整视图的大小或位置。中心物业   可以用来调整视图的位置而不改变它   尺寸。边界定义视图的内部尺寸   看到它们,几乎只用于自定义绘图代码。该   框架的大小部分和边界矩形耦合在一起   因此,更改任一矩形的大小会更新大小   两者。

我认为arrorBackgroundColor应该真正被称为arrowColor(因为它被用作箭头的颜色),你可能有另一个属性arrorBackgroundColor,它真正用于背景。我添加了两行填充背景,黄色为例。