I create a parent view with CAShapeLayer, and create a child button with 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)
}
}
createView
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)
}
It run at simular like this, parent view's CAShapeLayers cover its child button CAShapeLayers.
but it show in Debug View Hierarchy like this.
How do i sort them like Debug View Hierarchy? Thanks for answer!!
Don't create and add a new sublayer in draw(_ rect:)
. You don't control how often that method is called, and you are adding a new sublayer every time it is.
Overriding drawRect is generally not a great idea, since it can affect the drawing of other parts of the view and performance during animations.
Create and add the sublayer once, in your init method, for example, and position it if you need to in layoutSubviews
. Don't override draw(_ rect:)
.