如何在 UIView 和子按钮中对正确的 CAShapeLayers 进行排序?

How to sort correct CAShapeLayers in UIView and child button?

我用 CAShapeLayer 创建一个父视图,并用 CAShapeLayer 创建一个子按钮。

class TestButton: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 60, y: 100))
        path.addLine(to: CGPoint(x: 0, y: 100))
        path.addArc(withCenter: CGPoint(x: 100, y: 100), radius: 100, startAngle: .pi, endAngle: .pi*1.5, clockwise: true)
        path.addLine(to: CGPoint(x: 100, y: 60))
        path.addArc(withCenter: CGPoint(x: 100, y: 100), radius: 40, startAngle: .pi*1.5, endAngle: .pi, clockwise: false)
        path.close()
        
        let drawLayer = CAShapeLayer.init()
        drawLayer.path = self.path.cgPath
        drawLayer.fillColor = UIColor.green.cgColor
        self.layer.addSublayer(drawLayer)
    }
}

class TestView:UIView{
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: 0, y: rect.height-20))
        path.addLine(to: CGPoint(x: rect.width/2, y: rect.height))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height-20))
        path.addLine(to: CGPoint(x: rect.width, y: 0))
        path.addLine(to: CGPoint(x: 0, y: 0))
        path.close()
        
        let drawLayer = CAShapeLayer.init()
        drawLayer.path = self.path.cgPath
        drawLayer.fillColor = UIColor.red.cgColor
        self.layer.addSublayer(drawLayer)
    }
}

创建视图

func createView() {
    let announce = TestAnnotationview.init(frame: CGRect.init(x: 50, y: 400, width: 150, height: 150))
    announce.backgroundColor = .blue
    self.view.addSubview(announce)
    let btn = TestButton2.init(frame: CGRect.init(x: 0, y: 0, width: 150, height: 150))
    btn.backgroundColor = .yellow
    announce.addSubview(btn)
}

它运行类似这样,父视图的CAShapeLayers覆盖它的子按钮CAShapeLayers。

但它在调试视图层次结构中显示如下。

如何像调试视图层次结构一样对它们进行排序? 谢谢解答!!

不要在 draw(_ rect:) 中创建和添加新的子层。您无法控制调用该方法的频率,每次调用时都会添加一个新的子层。

覆盖 drawRect 通常不是一个好主意,因为它会影响视图其他部分的绘制和动画期间的性能。

创建并添加一次子层,例如,在您的 init 方法中,如果需要,将其放置在 layoutSubviews 中。不要覆盖 draw(_ rect:).