在图层之上绘制#rect 核心图形?

draw#rect core graphics, on top of a layer?

假设你在 UIView 中有这个,

override func draw(_ rect: CGRect) {
    let c = UIGraphicsGetCurrentContext()
    c?.setLineWidth(10.0)
    c?.move(to: CGPoint(x: 10.0, y: 10.0))
    c?.addLine(to: CGPoint(x: 40.0, y: 40.0))
    ... lots of complicated drawing here, sundry paths, colors, widths etc ...
    c?.strokePath()
}

当然,它会为你把你的画画出来。

但是说在同一个 UIView 中你这样做...

func setup() { // in inits, layout
    if nil etc {
      thingLayer = CAShapeLayer()
      self.layer.insertSublayer(thingLayer, at: 0)
      thingLayer.fillColor = UIColor.yellow.cgColor }
    thingLayer.frame = bounds
    let path = ... some fancy path
    thingLayer.path = path.cgPath
}

的确,新的黄色层被绘制over draw#rect.

中的绘图

您如何绘制 - 使用核心图形命令 - 在 thingLayer 上,或者可能在最上面的另一层上??

核心图形命令:

    let c = UIGraphicsGetCurrentContext()
    c?.setLineWidth(10.0)
    c?.move(to: CGPoint(x: 10.0, y: 10.0))
    c?.addLine(to: CGPoint(x: 40.0, y: 40.0))
    c?.strokePath()

似乎画到了主干道正上方或主干道上的某个地方.layer

(嗯,据我所知,似乎是这样。)

您如何绘制 - 使用核心图形命令 - 在 thingLayer 上,或者可能在最上面的另一层上??

当然可以在 draw#rect 中指定要绘制到哪个 cgLayer?

在 draw#rect 中,你可以制作另一个 cgLayer 并绘制到上下文,那个 cgLayer 吗?

CALayer 层次结构是一棵树,其中首先是根层(例如,包含 window 背景的层),然后是其 sublayers(数组CALayer 个对象,以从后到前的顺序存储和绘制),然后是它们的子层,依此类推。

您对 UIView.draw(_ rect: CGRect) 的实现定义了视图 (self.layer) 的主要图层的绘制方式。

通过将您的 CAShapeLayer 添加为 self.layer 的子层,您可以在 after self.layer 后绘制它,它具有它被绘制在 上方 self.layer 的效果,其中包含您在 UIView.draw(_ rect: CGRect).

中绘制的线

要解决此问题,您需要将笔画放在子层 之后 您的 thingLayer.

self.layer.insertSublayer(thingLayer, at: 0)
self.layer.insertSublayer(lineLayer, above: thingLayer)

对了,你忘了委托给super.draw(rect)。对于 UIView 的直接子类来说没有必要(因为基础实现什么都不做),但对于其他所有情况都是必要的,并且养成这种习惯通常是个好习惯(以免 运行进入真正的 obscure/frustrating 绘图错误)。

最重要的是,draw(_:) 用于呈现 UIView 子类的根视图。如果您添加子层,它们将在根视图 draw(_:).

中所做的任何事情之上呈现

如果您当前在 draw(_:) 中执行了一些路径,您希望在已添加的子层之上呈现这些路径,您有几个选择:

  1. 将要描边的路径移动到它们自己的 CAShapeLayer 实例中,并将它们添加到您已经添加的其他子层之上。

  2. 将主 UIView 子类视为 container/content 视图,并添加您自己的私有 UIView 子视图(可能带有“复杂的” draw(_:) 方法)。如果你不想,你不必公开这些私有子视图。

  3. 将复杂的绘图移动到 CALayer 子类的 draw(in:),然后再次将此子层添加到您已经创建的现有子层之上。

  4. 鉴于 thingLayer 实际上只是设置背景颜色,您可以只设置视图的背景颜色,根本不使用图层作为背景颜色。

如果您的黄色形状图层不会独立改变或四处移动,您可以去掉 CAShapeLayer 并在 draw(_:):

实现的顶部自己绘制形状
let path = // your fancy UIBezierPath
UIColor.yellow.setFill()
path.fill()

否则,正如其他评论者所说,您需要将绘图代码移动到 UIView 或 CALayer 的其他自定义子类中,并按您想要的顺序堆叠它们。