对CAShapeLayer进行遮罩会创建此奇怪的伪像吗? [英] Masking a CAShapeLayer creates this weird artifact?

查看:105
本文介绍了对CAShapeLayer进行遮罩会创建此奇怪的伪像吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为任务列表创建一个平滑的进度栏。我使用了一个圆圈(CGMutablePath),该圆圈掩盖了灰色区域,并且有明显的弧形伪像。不仅如此,栏的右侧还有一个人工制品。



注意:我试图将图层栅格化无济于事。



是什么原因导致iOS做到这一点以及如何做我可以解决这个问题还是摆脱它?

  priv var circleMask:CAShapeLayer = CAShapeLayer()
覆盖函数layoutSubviews(){
super.layoutSubviews()
backgroundColor = GradientColor(.leftToRight,frame:self.bounds,color: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()


}

私有函数createMask( ){
let path = CGMutablePath()
path.addArc(center:CGPoint(x:bounds.origin.x + 25/2,y:bounds.origin.y + 25/2),半径:25/2,startAngle:0,结束角度:CGFloat(Double.pi * 2),顺时针:false)
path.addRect(bounds)
circleMask.path =路径
circleMask.backgroundColor = plainMeterColor.cgColor
circleMask .fillRule = kCAFillRuleEvenOdd
plainProgressBar.layer.mask = circleMask
}

< a href = https://i.stack.imgur.com/Vk6CR.jpg rel = nofollow noreferrer>

解决方案

问题显然是抗锯齿边缘的组成存在错误。 / p>

混蛋问题:您是否设置了非典型混合模式?



最简单的解决方案:不使用 path.addArc path.addRect 生成两个完全不同的形状。只需使用 init(roundedRect:... 方法之一,并将拐角半径设置为高度的一半,将总路径延伸到左侧可用空间之外即可创建一个



或者,如果没有出现,则手动构造路径,作为移动 addLine(to: addArc 仅半圈,然后最后一个 addLine(to: close 。(未经测试,尤其是re:开始和结束角度以及顺时针与逆时针以及iOS的上下颠倒坐标系)

 私有函数createMask(){
let path = CGMutablePath()
path.move(to:CGPoint(x :0,y:0))
path.addLine(至: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),半径:25/2,startAngle:CGFloat(Double.pi / 2.0),endAngle:CGFloat(Double.pi * 3.0 /2.0),顺时针:false)
path.addLine(to:CGPoint(x:0 ,y:25))
path.close()
...


I want to create a smooth progress bar for a to-do list. I used a circle (CGMutablePath) that masks the gray area and there's an obvious arc-like artifact. Not only that but there's also an artifact on the right side of the bar.

Note: I tried to rasterize the layers to no avail.

What causes iOS to do this and how can I smooth this out or get rid of it?

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
}

解决方案

The issue is clearly an error in composition of the antialiased edges.

Knee-jerk question: do you have an atypical blend mode set?

Easiest solution: don't use path.addArc and path.addRect to generate two completely distinct shapes. Just use one of the init(roundedRect:... methods and set a corner radius of half your height, stretching the total path beyond the available space to the left to create a hard edge.

Or, if that doesn't appear, construct the path manually as a move, addLine(to:, addArc of only half a circle, then a final addLine(to: and a close. E.g. (thoroughly untested, especially re: start and end angles and clockwise versus anticlockwise versus iOS's upside-down coordinate system)

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()
    ...

这篇关于对CAShapeLayer进行遮罩会创建此奇怪的伪像吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆