Ios 在图层的顶部绘制#rect core图形?

Ios 在图层的顶部绘制#rect core图形?,ios,swift,core-graphics,Ios,Swift,Core Graphics,假设你有这个观点 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, sundr

假设你有这个观点

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()
}
当然,这会让你的画变得更糟

但是用同样的观点说你这样做

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
}
实际上,新的黄色图层是在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()
似乎画到了正上方或主层上的某个位置

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

如何使用核心图形命令在thingLayer上绘制,或者在其他图层上绘制

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


在draw#rect中,您能否制作另一个cgLayer并绘制到上下文中,即cgLayer?

层次结构是一棵树,其中根层是第一层(例如,构成窗口背景的层),然后是其
子层(一组
CALayer
对象,按从后到前的顺序存储和绘制),然后是它们的子层,以此类推

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

通过将您的
CAShapeLayer
添加为
self.layer
的子层,您可以在
self.layer
之后绘制它,其效果是在
self.layer
上方绘制它,该层包含您在
UIView.draw(rect:cgrct)
中绘制的线条

要解决这个问题,您需要将笔划放在
thingLayer
之后的子层中

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

顺便说一句,您忘了委托给
super.draw(rect)
。对于
UIView
的直接子类来说,这是不必要的(因为基本实现不起任何作用),但是对于其他情况来说,这是必要的,而且这通常是一个好习惯(以免您遇到真正模糊/令人沮丧的绘图错误)

底线是,用于呈现
UIView
子类的根视图。如果添加子层,则它们将在根视图的
绘制(u1;:)
中所做的任何操作之上进行渲染

如果当前在
绘图(:)
中执行了一些路径,您希望在已添加的子层上渲染这些路径,则有几个选项:

  • 将要笔划的路径移动到它们自己的
    CAShapeLayer
    实例中,并将它们添加到已添加的其他子层之上

  • 将主
    UIView
    子类视为容器/内容视图,并添加您自己的私有
    UIView
    子视图(可能使用“复杂的”
    draw(quo;:)
    方法)。如果不想,您不必公开这些私有子视图

  • 将复杂图形移动到
    CALayer
    子类的顶部,再次将此子层添加到已创建的现有子层之上

  • 考虑到
    thingLayer
    实际上只是设置背景色,您可以只设置视图的背景色,而不使用图层作为背景色


  • 如果您的黄色形状层没有单独改变或移动,您可以去掉CAShapeLayer,只需在
    draw(:)
    实现的顶部自己绘制形状即可:


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

    顺便说一句,如果您根据
    边界执行任何操作,您将需要将其移动到
    布局子视图中。
    。我不确定您是否注意到,我给每一个QA都增加了奖金。“一个或多个答案是典型的,值得额外奖励。”我发现,它通常会带来更多的兴趣和其他有价值的想法、答案或评论。再次感谢!“用于呈现UIView子类的根视图”-ahhhhh。(那么,根cgLayer,对吗?它在根.layer上)在某种意义上@Rob item 3是“问题的答案”。如果你真的想在另一个图层上使用draw#rect direct命令,那么你似乎必须对图层进行子类化并使用draw#in。用户Alexander在评论中也提到了这一点。@Fattie为什么是的,我确实这么说了。不知何故,我们的评论和内容被删除了。这是怎么回事?罗宾,没错:但总的来说,在计算中把东西分开是件好事。一个例子是,我们可能会以这样或那样的方式设置一些有问题的层的动画;在这种情况下,设置不同的层是非常明智/容易的。
    let path = // your fancy UIBezierPath
    UIColor.yellow.setFill()
    path.fill()