// 簡單、高效、GPU 直接渲染
layer.backgroundColor = UIColor.green.cgColor
// 或帶透明度
layer.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 0.5).cgColor
優點:無需繪製回調、性能最佳、動畫平滑 (可隱式動畫)。
缺點:僅支持純色、漸變需用 CAGradientLayer、複雜形狀無能為力。
class CustomShapeLayer: CALayer {
override func draw(in ctx: CGContext) {
super.draw(in: ctx)
// 1. 定義路徑 (例:圓角矩形、多邊形、貝塞爾曲線)
let path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
ctx.addPath(path)
// 2. 設置填充顏色
ctx.setFillColor(UIColor.systemBlue.cgColor)
// 或漸變
// let gradient = CGGradient(...)
// ctx.drawLinearGradient(gradient, start: ..., end: ..., options: [])
// 3. 填充路徑
ctx.fillPath()
// 4. 可選:描邊
ctx.setStrokeColor(UIColor.white.cgColor)
ctx.setLineWidth(2)
ctx.addPath(path)
ctx.strokePath()
}
}
// 使用
let shapeLayer = CustomShapeLayer()
shapeLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
view.layer.addSublayer(shapeLayer)
// 觸發重繪 (bounds 變化自動觸發,或手動)
shapeLayer.setNeedsDisplay()
// .m
- (void)drawInContext:(CGContextRef)ctx {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:12];
[path addClip]; // 可選:裁剪上下文
[[UIColor greenColor] setFill];
UIRectFill(self.bounds); // 或 CGContextFillPath(ctx) 配合 path
// 邊框
[[UIColor whiteColor] setStroke];
path.lineWidth = 2;
[path stroke];
}
| 技巧 | 說明 |
|---|---|
shouldRasterize = YES | 光柵化緩存離屏渲染結果,複雜繪製提升幀率 |
rasterizationScale = [UIScreen mainScreen].scale | 匹配螢幕縮放,避免模糊 |
| 避免在 drawInContext 中分配對象 | 路徑、顏色、漸變預先創建複用 |
| 優先用 CAShapeLayer | 聲明式路徑 + fillColor/strokeColor,GPU 加速、無需重寫 drawInContext |
let shapeLayer = CAShapeLayer()
shapeLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
shapeLayer.fillColor = UIColor.systemBlue.cgColor
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.lineWidth = 2
// 支持隱式動畫!
view.layer.addSublayer(shapeLayer)
優勢:聲明式、GPU 渲染、屬性動畫原生支持、無需子類化、代碼極簡。
layer.backgroundColorCAShapeLayer (首選)CAGradientLayer / 多層疊加drawInContext + shouldRasterize