Swift: 如何继承 CALayer 使其自动调整大小?
Swift: How to subclass CALayer so it resizes automatically?
已知 UIView
的 main/root 图层,例如 view.layer
,将自动调整大小以填充 UIView
的框架(但是,根层的子层不会自动调整大小。
子类化后 CALayer
如:
class CustomLayer : CALayer {
//...
}
我可以实现哪些方法来“绘制”内容以便图层在用作视图的根 CALayer 时自动调整大小?
之所以这么问是因为我目前调用的方法如:
UIBezierPath(roundedRect: self.view.frame, byRoundingCorners: [.topLeft], cornerRadii: CGSize(width: 17, height: 15))
要更新 CALayer 的路径,但是如果能够创建一个自定义 CALayer
可以作为 UIView
的根层,那将是非常棒的,所以我不需要持续更新其路径。
有人对此有什么建议吗?最终,我正在努力拥有一个图层,该图层可以支持 每个角的独特半径 ,它将自动填充 UIView
并调整大小,而无需持续更新框架。
您可以子类化 UIView,覆盖 layerClass 和 return 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)
}
}
已知 UIView
的 main/root 图层,例如 view.layer
,将自动调整大小以填充 UIView
的框架(但是,根层的子层不会自动调整大小。
子类化后 CALayer
如:
class CustomLayer : CALayer {
//...
}
我可以实现哪些方法来“绘制”内容以便图层在用作视图的根 CALayer 时自动调整大小?
之所以这么问是因为我目前调用的方法如:
UIBezierPath(roundedRect: self.view.frame, byRoundingCorners: [.topLeft], cornerRadii: CGSize(width: 17, height: 15))
要更新 CALayer 的路径,但是如果能够创建一个自定义 CALayer
可以作为 UIView
的根层,那将是非常棒的,所以我不需要持续更新其路径。
有人对此有什么建议吗?最终,我正在努力拥有一个图层,该图层可以支持 每个角的独特半径 ,它将自动填充 UIView
并调整大小,而无需持续更新框架。
您可以子类化 UIView,覆盖 layerClass 和 return 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)
}
}