屏蔽 CAShapeLayer 会产生这个奇怪的工件?
Masking a CAShapeLayer creates this weird artifact?
我想为待办事项列表创建一个流畅的进度条。我使用了一个圆圈 (CGMutablePath) 来掩盖灰色区域,并且有一个明显的弧形伪影。不仅如此,在栏的右侧还有一个神器。
注意:我尝试对图层进行栅格化,但没有成功。
是什么原因导致 iOS 出现这种情况,我该如何解决或消除它?
private var circleMask: CAShapeLayer = CAShapeLayer()
override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = GradientColor(.leftToRight, frame: self.bounds, colors: GradientFlatRed())
layer.cornerRadius = bounds.height / 2
plainProgressBar.layer.cornerRadius = layer.cornerRadius
layer.shouldRasterize = true
layer.rasterizationScale = UIScreen.main.scale
plainProgressBar.layer.shouldRasterize = true
plainProgressBar.layer.rasterizationScale = UIScreen.main.scale
createMask()
}
private func createMask() {
let path = CGMutablePath()
path.addArc(center: CGPoint(x: bounds.origin.x+25/2, y: bounds.origin.y+25/2), radius: 25/2, startAngle: 0, endAngle: CGFloat(Double.pi*2), clockwise: false)
path.addRect(bounds)
circleMask.path = path
circleMask.backgroundColor = plainMeterColor.cgColor
circleMask.fillRule = kCAFillRuleEvenOdd
plainProgressBar.layer.mask = circleMask
}
问题显然是抗锯齿边缘的合成错误。
下意识问题:您是否设置了非典型混合模式?
最简单的解决方案:不要使用 path.addArc
和 path.addRect
生成两个完全不同的形状。只需使用其中一种 init(roundedRect:...
方法并将拐角半径设置为您身高的一半,将总路径向左延伸超出可用 space 以创建硬边。
或者,如果没有出现,手动将路径构造为仅半个圆的 move
、addLine(to:
、addArc
,然后是最后的 addLine(to:
和 close
。例如。 (完全未经测试,尤其是关于:开始和结束角度以及顺时针与逆时针与 iOS 的颠倒坐标系)
private func createMask() {
let path = CGMutablePath()
path.move(to: CGPoint(x: 0, y:0))
path.addLine(to: CGPoint(x: bounds.origin.x+25/2, y: 0))
path.addArc(center: CGPoint(x: bounds.origin.x+25/2, y: bounds.origin.y+25/2), radius: 25/2, startAngle: CGFloat(Double.pi/2.0), endAngle: CGFloat(Double.pi*3.0/2.0), clockwise: false)
path.addLine(to: CGPoint(x: 0, y: 25))
path.close()
...
我想为待办事项列表创建一个流畅的进度条。我使用了一个圆圈 (CGMutablePath) 来掩盖灰色区域,并且有一个明显的弧形伪影。不仅如此,在栏的右侧还有一个神器。
注意:我尝试对图层进行栅格化,但没有成功。
是什么原因导致 iOS 出现这种情况,我该如何解决或消除它?
private var circleMask: CAShapeLayer = CAShapeLayer()
override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = GradientColor(.leftToRight, frame: self.bounds, colors: GradientFlatRed())
layer.cornerRadius = bounds.height / 2
plainProgressBar.layer.cornerRadius = layer.cornerRadius
layer.shouldRasterize = true
layer.rasterizationScale = UIScreen.main.scale
plainProgressBar.layer.shouldRasterize = true
plainProgressBar.layer.rasterizationScale = UIScreen.main.scale
createMask()
}
private func createMask() {
let path = CGMutablePath()
path.addArc(center: CGPoint(x: bounds.origin.x+25/2, y: bounds.origin.y+25/2), radius: 25/2, startAngle: 0, endAngle: CGFloat(Double.pi*2), clockwise: false)
path.addRect(bounds)
circleMask.path = path
circleMask.backgroundColor = plainMeterColor.cgColor
circleMask.fillRule = kCAFillRuleEvenOdd
plainProgressBar.layer.mask = circleMask
}
问题显然是抗锯齿边缘的合成错误。
下意识问题:您是否设置了非典型混合模式?
最简单的解决方案:不要使用 path.addArc
和 path.addRect
生成两个完全不同的形状。只需使用其中一种 init(roundedRect:...
方法并将拐角半径设置为您身高的一半,将总路径向左延伸超出可用 space 以创建硬边。
或者,如果没有出现,手动将路径构造为仅半个圆的 move
、addLine(to:
、addArc
,然后是最后的 addLine(to:
和 close
。例如。 (完全未经测试,尤其是关于:开始和结束角度以及顺时针与逆时针与 iOS 的颠倒坐标系)
private func createMask() {
let path = CGMutablePath()
path.move(to: CGPoint(x: 0, y:0))
path.addLine(to: CGPoint(x: bounds.origin.x+25/2, y: 0))
path.addArc(center: CGPoint(x: bounds.origin.x+25/2, y: bounds.origin.y+25/2), radius: 25/2, startAngle: CGFloat(Double.pi/2.0), endAngle: CGFloat(Double.pi*3.0/2.0), clockwise: false)
path.addLine(to: CGPoint(x: 0, y: 25))
path.close()
...