在图层之上绘制#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(_:)
中执行了一些路径,您希望在已添加的子层之上呈现这些路径,您有几个选择:
将要描边的路径移动到它们自己的 CAShapeLayer
实例中,并将它们添加到您已经添加的其他子层之上。
将主 UIView
子类视为 container/content 视图,并添加您自己的私有 UIView
子视图(可能带有“复杂的” draw(_:)
方法)。如果你不想,你不必公开这些私有子视图。
将复杂的绘图移动到 CALayer
子类的 draw(in:)
,然后再次将此子层添加到您已经创建的现有子层之上。
鉴于 thingLayer
实际上只是设置背景颜色,您可以只设置视图的背景颜色,根本不使用图层作为背景颜色。
如果您的黄色形状图层不会独立改变或四处移动,您可以去掉 CAShapeLayer 并在 draw(_:)
:
实现的顶部自己绘制形状
let path = // your fancy UIBezierPath
UIColor.yellow.setFill()
path.fill()
否则,正如其他评论者所说,您需要将绘图代码移动到 UIView 或 CALayer 的其他自定义子类中,并按您想要的顺序堆叠它们。
假设你在 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(_:)
中执行了一些路径,您希望在已添加的子层之上呈现这些路径,您有几个选择:
将要描边的路径移动到它们自己的
CAShapeLayer
实例中,并将它们添加到您已经添加的其他子层之上。将主
UIView
子类视为 container/content 视图,并添加您自己的私有UIView
子视图(可能带有“复杂的”draw(_:)
方法)。如果你不想,你不必公开这些私有子视图。将复杂的绘图移动到
CALayer
子类的draw(in:)
,然后再次将此子层添加到您已经创建的现有子层之上。鉴于
thingLayer
实际上只是设置背景颜色,您可以只设置视图的背景颜色,根本不使用图层作为背景颜色。
如果您的黄色形状图层不会独立改变或四处移动,您可以去掉 CAShapeLayer 并在 draw(_:)
:
let path = // your fancy UIBezierPath
UIColor.yellow.setFill()
path.fill()
否则,正如其他评论者所说,您需要将绘图代码移动到 UIView 或 CALayer 的其他自定义子类中,并按您想要的顺序堆叠它们。