Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何仅填充CAShapeLayer上形状的一部分_Ios_Swift_Uibezierpath_Swift5_Cashapelayer - Fatal编程技术网

Ios 如何仅填充CAShapeLayer上形状的一部分

Ios 如何仅填充CAShapeLayer上形状的一部分,ios,swift,uibezierpath,swift5,cashapelayer,Ios,Swift,Uibezierpath,Swift5,Cashapelayer,我用UIBezierPath创建以下形状,然后用CAShapeLayer绘制它,如下所示 // left Circle shapeLayer1.path = bezierPath1.cgPath shapeLayer1.fillColor = UIColor.blue.cgColor // line shapeLayer2.path = bezierPath2.cgPath // right Circle shapeLayer3.path = bezierPath3.cgPath shape

我用UIBezierPath创建以下形状,然后用CAShapeLayer绘制它,如下所示

// left Circle
shapeLayer1.path = bezierPath1.cgPath
shapeLayer1.fillColor = UIColor.blue.cgColor

// line
shapeLayer2.path = bezierPath2.cgPath

// right Circle
shapeLayer3.path = bezierPath3.cgPath
shapeLayer3.fillColor = UIColor.clear.cgColor

self.view.layer.addSublayer(shapeLayer1)
self.view.layer.addSublayer(shapeLayer2)
self.view.layer.addSublayer(shapeLayer3)

然后我可以将CAShapeLayer fillColor属性从
shapeLayer.fillColor=UIColor.clear.cgColor
更改为
shapeLayer.fillColor=UIColor.blue.cgColor
,并获得以下形状

代码如下:

import UIKit

class ViewController: UIViewController {

    var line = [CGPoint]()
    let bezierPath: UIBezierPath = UIBezierPath()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        let point1 = CGPoint(x: 100, y: 100)
        let point2 = CGPoint(x: 400, y: 100)

        line.append(point1)
        line.append(point2)

        addCircle(toRight: false)
        addLine()
        addCircle(toRight: true)

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = bezierPath.cgPath
        shapeLayer.strokeColor = UIColor.blue.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor

         self.view.layer.addSublayer(shapeLayer)
    }

    func addLine() -> Void {
        bezierPath.move(to: line.first!)
        bezierPath.addLine(to: line.last!)
    }

    func addCircle(toRight: Bool) -> Void {
        let angle = CGFloat( Double.pi / 180 )
        let r = CGFloat(20.0)
        let x0 = toRight ? line.first!.x : line.last!.x
        let y0 = toRight ? line.first!.y : line.last!.y
        let x1 =  toRight ? line.last!.x : line.first!.x
        let y1 = toRight ? line.last!.y : line.first!.y
        let x = x1 - x0
        let y = y1 - y0
        let h = (x*x + y*y).squareRoot()
        let x2 = x0 + (x * (h + r) / h)
        let y2 = y0 + (y * (h + r) / h)

        // Add the arc, starting at that same point
        let point2 = CGPoint(x: x2, y: y2)
        let pointZeroDeg = CGPoint(x: x2 + r, y: y2)
        self.bezierPath.move(to: pointZeroDeg)
        self.bezierPath.addArc(withCenter: point2, radius: r,
                          startAngle: 0*angle, endAngle: 360*angle,
                          clockwise: true)
        self.bezierPath.close()
    }
}
但我真正想要的是下面的形状(左侧圆是填充的,右侧圆不是填充的)

所以我的问题是,如何只填充CAShapeLayer上的一部分形状? 可能吗?有什么诀窍可以做到这一点吗

PS:我可以通过创建3个不同的UIBezierPath(用于leftCircle、line和rightCircle)并使用3个不同的CashapeLayer绘制它们来实现这一点,如下所示

// left Circle
shapeLayer1.path = bezierPath1.cgPath
shapeLayer1.fillColor = UIColor.blue.cgColor

// line
shapeLayer2.path = bezierPath2.cgPath

// right Circle
shapeLayer3.path = bezierPath3.cgPath
shapeLayer3.fillColor = UIColor.clear.cgColor

self.view.layer.addSublayer(shapeLayer1)
self.view.layer.addSublayer(shapeLayer2)
self.view.layer.addSublayer(shapeLayer3)

但我更喜欢用一个CAShapeLayer来实现这一点

我认为更好的方法是使用多种形状

但是,您可以使用
evenOdd
形状填充规则来实现一个形状

只需在方法
addCircle
中的右圆圈中添加一个额外的圆圈:

if toRight {
    self.bezierPath.addArc(withCenter: point2, radius: r,
                      startAngle: 0*angle, endAngle: 2*360*angle,
                      clockwise: true)
} else {
    self.bezierPath.addArc(withCenter: point2, radius: r,
                      startAngle: 0*angle, endAngle: 360*angle,
                      clockwise: true)
}
并将
fillRule
设置为
evenOdd

shapeLayer.fillColor = UIColor.blue.cgColor        
shapeLayer.fillRule = .evenOdd
因此,您将得到左边的圆将有一个绘图圆,并将由
evenOdd
规则填充。但右边的圆圈将有两个画圈,并且将不填充

evenOdd
规则():

指定奇偶缠绕规则。计算路径的总数 过境点。如果交叉口的数量为偶数,则该点位于外侧 这条路。如果交叉点的数量为奇数,则该点位于 路径和包含它的区域应该被填充