It is known that the main/root layer of a UIView
, e.g., view.layer
, will resize automatically to fill the frame of the UIView
(however, a root layer's sublayers will not automatically resize).
After subclassing CALayer
like:
class CustomLayer : CALayer {
//...
}
What methods can I implement to "draw" content so that the layer will automatically resize if used as the root CALayer of a view?
The reason I ask this is because I am current calling methods such as:
UIBezierPath(roundedRect: self.view.frame, byRoundingCorners: [.topLeft], cornerRadii: CGSize(width: 17, height: 15))
To update the path of a CALayer, but it would be amazing to be able to create a custom CALayer
that can act as a root layer for a UIView
so I don't need to consistently update its path.
Does anyone have any advice for this? Ultimately I'm striving to have a layer that can support unique radii for each corner that will automatically fill the UIView
and resize without having to consistently update the frame.
You can subclass UIView, override layerClass and return a CAShapeLayer:
class Shape: UIView {
override public class var layerClass: AnyClass { CAShapeLayer.self }
var shapeLayer: CAShapeLayer { layer as! CAShapeLayer }
private var bezierPath: UIBezierPath = UIBezierPath() { didSet { shapeLayer.path = bezierPath.cgPath } }
var fillColor: UIColor = .green { didSet { shapeLayer.fillColor = fillColor.cgColor } }
var strokeColor: UIColor = .blue { didSet { shapeLayer.strokeColor = strokeColor.cgColor } }
var lineWidth: CGFloat = 2 { didSet { shapeLayer.lineWidth = lineWidth } }
override func didMoveToSuperview() {
updateShape()
shapeLayer.fillColor = fillColor.cgColor
shapeLayer.strokeColor = strokeColor.cgColor
shapeLayer.lineWidth = lineWidth
}
func updateShape() {
bezierPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.topLeft], cornerRadii: CGSize(width: 17, height: 15))
}
override func layoutSubviews() {
super.layoutSubviews()
print(#function)
updateShape()
}
override public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
print(#function)
// you can change the color of your shape here if needed (dark/light mode)
}
}