CGContext 绘制两个相邻的菱形产生了一个很细的间隙,如何减少它?

CGContext Drawing two adjacent rhomboids produce a very thin gap, how to reduce it?

两个相邻的矩形就可以了,如下图。

override func draw(_ rect: CGRect) {
    // Drawing code
    let leftTop = CGPoint(x:50,y:50)
    let rightTop = CGPoint(x:150,y:100)

    let leftMiddle = CGPoint(x:50,y:300)
    let rightMiddle = CGPoint(x:150,y:300)

    let leftDown = CGPoint(x:50,y:600)
    let rightDown = CGPoint(x:150,y:650)

    let context = UIGraphicsGetCurrentContext()
    context?.addLines(between: [leftTop,rightTop,rightMiddle,leftMiddle])
    UIColor.black.setFill()
    context?.fillPath()

    context?.addLines(between: [leftMiddle,rightMiddle,rightDown,leftDown])
    context?.fillPath()


    let leftTop1 = CGPoint(x:200,y:50)
    let rightTop1 = CGPoint(x:300,y:100)

    let leftMiddle1 = CGPoint(x:200,y:300)
    let rightMiddle1 = CGPoint(x:300,y:350)

    let leftDown1 = CGPoint(x:200,y:600)
    let rightDown1 = CGPoint(x:300,y:650)

    context?.addLines(between: [leftTop1,rightTop1,rightMiddle1,leftMiddle1])
    UIColor.black.setFill()
    context?.fillPath()

    context?.addLines(between: [leftMiddle1,rightMiddle1,rightDown1,leftDown1])
    context?.fillPath()
}

您可能需要放大才能看到差距。如果我画一条细线来覆盖间隙,那么如果颜色有 alpha 通道,任何宽度都可能重叠。

将 shapeColor 更改为 let shapeColor = UIColor(white: 0.0, alpha: 0.5) 并添加 context?.setShouldAntialias(false)

即使我使用 setShouldAntialias(true) 或者如果我尝试在上下文中调用 strokePath() ,我使用 CGContext 也会得到相同的结果。但它适用于 sublayersCGPathstrokeColor

class RhombView: UIView {
    let shapeColor: UIColor = .black

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setupView()
    }

    func setupView() {
        let leftTop1 = CGPoint(x:200.0,y:50.0)
        let rightTop1 = CGPoint(x:300.0,y:100.0)

        let leftMiddle1 = CGPoint(x:200.0,y:300.0)
        let rightMiddle1 = CGPoint(x:300.0,y:350.0)

        let leftDown1 = CGPoint(x:200.0,y:600.0)
        let rightDown1 = CGPoint(x:300.0,y:650.0)

        var path = UIBezierPath()

        path.move(to: leftTop1)
        path.addLine(to: rightTop1)
        path.addLine(to: rightMiddle1)
        path.addLine(to: leftMiddle1)
        path.close()

        let subLayer1 = CAShapeLayer()
        subLayer1.path = path.cgPath
        subLayer1.frame = self.layer.frame
        subLayer1.fillColor = shapeColor.cgColor
        subLayer1.strokeColor = shapeColor.cgColor
        self.layer.addSublayer(subLayer1)

        path = UIBezierPath()

        path.move(to: leftMiddle1)
        path.addLine(to: rightMiddle1)
        path.addLine(to: rightDown1)
        path.addLine(to: leftDown1)
        path.close()

        let subLayer2 = CAShapeLayer()
        subLayer2.path = path.cgPath
        subLayer2.frame = self.layer.frame
        subLayer2.fillColor = shapeColor.cgColor
        subLayer2.strokeColor = shapeColor.cgColor
        self.layer.addSublayer(subLayer2)

        self.layer.backgroundColor = UIColor.white.cgColor
    }
}

如果你删除两个 subLayer.strokeColor 你会看到差距。

这与屏幕分辨率有关。在具有高分辨率的设备上,一个点实际上有 2 或 3 个像素。这就是为什么绘制一条斜线 iOS 会绘制一些具有一定不透明度的边缘像素,当 2 条线彼此相邻时,这些边缘像素会重叠。在你的情况下,我能够通过进行以下更改来解决问题

        let leftTop1 = CGPoint(x:200,y:50)
    let rightTop1 = CGPoint(x:300,y:100)

    let leftMiddle1 = CGPoint(x:200,y:300)
    let rightMiddle1 = CGPoint(x:300,y:350)

    let leftMiddle2 = CGPoint(x:200,y:300.333)
    let rightMiddle2 = CGPoint(x:300,y:350.333)

    let leftDown1 = CGPoint(x:200,y:600)
    let rightDown1 = CGPoint(x:300,y:650)

    context?.addLines(between: [leftTop1,rightTop1,rightMiddle1,leftMiddle1])
    UIColor.black.setFill()

    context?.fillPath()

    context?.addLines(between: [leftMiddle2,rightMiddle2,rightDown1,leftDown1])
    context?.fillPath()

基本上将第二个菱形向下移动 1 个像素(1/3 = 0.333...),我已经在具有 1:3 像素密度的屏幕上进行了测试,以便解决方案适用于您的所有设备我们需要检查屏幕的比例因子。