【问题标题】:CAShapeLayer groove pathCAShapeLayer 凹槽路径
【发布时间】:2017-11-18 10:07:01
【问题描述】:

我想制作一个白色视图,里面有一个三角形指针,如下所示:

如上图所示,目标是在whiteview 中创建一个“圆形凹槽”嵌入

    let pointerRadius:CGFloat = 4
    pointerLayer = CAShapeLayer()
    pointerLayer.path = pointerPathForContentSize(contentSize: bounds.size).cgPath
    pointerLayer.lineJoin = kCALineJoinRound
    pointerLayer.lineWidth = 2*pointerRadius
    pointerLayer.fillColor = UIColor.white.cgColor
    pointerLayer.strokeColor = UIColor.black.cgColor
    pointerLayer.backgroundColor = UIColor.white.cgColor

    layer.addSublayer(pointerLayer)

但我得到的是:

但是,如果我将描边颜色设置为白色

pointerLayer.strokeColor = UIColor.white.cgColor 

在凹槽中,我想在底部有一个rounded edge(就像在第一张图片中一样),当 fillColor 和 strokeColor 匹配(都是白色)时,它不再可见。 我该如何解决? 有没有其他方法可以做到这一点?

这里是指针路径的代码:

private func pointerPathForContentSize(contentSize: CGSize) -> UIBezierPath
{
    let rect = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height)

    let width:CGFloat = 20
    let height:CGFloat = 20

    let path = UIBezierPath()


    let startX:CGFloat = 50
    let startY:CGFloat = rect.minY
    path.move(to: CGPoint(x: startX , y: startY))
    path.addLine(to: CGPoint(x: (startX + width*0.5), y: startY + height))


    path.addLine(to: CGPoint(x: (startX + width), y: startY))

    path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
    path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
    path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
    path.addLine(to: CGPoint(x: rect.minX, y: rect.minY))


    path.close()
    return path
}

【问题讨论】:

  • 图层描边是内部视图,而不是它们之外;这就是为什么当线条为白色时您看不到凹槽。
  • 那我该如何解决呢?
  • 不清楚你在问什么。有什么问题?你得到的结果有什么问题?你想达到什么目的?
  • 凹槽底部有一个圆形边缘,当填充颜色和描边颜色匹配时,它不再可见。
  • 最后我得到了一个尖凹槽

标签: ios swift cashapelayer


【解决方案1】:

由于您已经通过描边路径勾勒出您想要的形状,我认为最简单的解决方案可能是使用描边和填充的路径作为蒙版。

例如,这里是一个矩形的红色视图:

这是相同的红色视图,顶部有缺口。这似乎是你所追求的那种东西:

我所做的是用一个特殊的蒙版视图来蒙版红色视图,该蒙版视图使用.clear 混合模式绘制缺口:

class MaskView : UIView {
    override init(frame: CGRect) {
        super.init(frame:frame)
        self.isOpaque = false
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func draw(_ rect: CGRect) {
        let con = UIGraphicsGetCurrentContext()!
        con.fill(self.bounds)
        con.setBlendMode(.clear)
        con.move(to: CGPoint(x:0, y:-4))
        con.addLine(to: CGPoint(x:100, y:-4))
        con.addLine(to: CGPoint(x:110, y:15))
        con.addLine(to: CGPoint(x:120, y:-4))
        con.addLine(to: CGPoint(x: self.bounds.maxX, y:-4))
        con.addLine(to: CGPoint(x: self.bounds.maxX, y:-20))
        con.addLine(to: CGPoint(x: 0, y:-20))
        con.closePath()
        con.setLineJoin(.round)
        con.setLineWidth(10)
        con.drawPath(using: .fillStroke) // stroke it and fill it
    }
}

那么,当我准备好在红色视图上剪掉缺口时,我就说:

self.redView.mask = MaskView(frame:self.redView.bounds)

【讨论】:

  • 感谢您的时间和精力!我可以将 replacePathWithStrokedPath 与 CAShapeLayer 或 UIBezierPath 一起使用吗?还是在drawRect 工作是现在唯一可行的方法?
  • 其实我是个白痴。你根本不需要replacePathWithStrokedPath。你只需要面具的想法。修改了我的代码。
  • 虽然它工作得很好,但我想知道只有凹槽弯曲而不是其他线条?
  • 因为我将整个蒙版向上推,这样它就不会与视图重叠并切断其顶部。这就是我代码中的-4 的含义。您可以将其移回0,但这会切断红色视图的顶部。由你决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多