CSS 带有鼓舞人心的评论
background: radial-gradient(423.17% 112.48% at 32.67% 115.21%, #FFD3D3 7.4%, #E7B9B9 24.14%, #596EBB 58.01%, #382A8B 96.1%) /* warning: gradient uses a rotation that is not supported by CSS and may not behave as expected */;
导出屏幕时 svg 的相关部分:
这产生了令人厌恶的代码,其起点和终点是我从墙上摘下来的:
static func shouldMakeGradientLayer(frame: CGRect? = nil) -> CAGradientLayer {
let gradientLayer = CAGradientLayer()
// Define colors
gradientLayer.colors = [
UIColor(hex: 0xFFD3D3).cgColor,
UIColor(hex: 0xE7B9B9).cgColor,
UIColor(hex: 0x596EBB).cgColor,
UIColor(hex: 0x382A8B).cgColor
].reversed()
// Define locations
//background: radial-gradient(423.17% 112.48% at 32.67% 115.21%, #FFD3D3 7.4%, #E7B9B9 24.14%, #596EBB 58.01%, #382A8B 96.1%) /* warning: gradient uses a rotation that is not supported by CSS and may not behave as expected */;
// gradientLayer.locations = [0.0739577, 0.241399, 0.580144, 0.961]
// make a guess :-[ gradientLayer.locations = [0, 0.8, 0.9, 1
// Apply the gradient transform
gradientLayer.type = .radial
// let transform = CATransform3DMakeRotation(-71.2512 * (.pi / 180), 0, 0, 1)
guard let w = frame?.width, let h = frame?.height else {
return gradientLayer
}
// gradientLayer.transform = CATransform3DConcat(CATransform3DMakeScale(964.534/w, 1675.8/w, 1), transform)
// gradientLayer.position = CGPoint(x: 122.5, y: 935.5)
gradientLayer.transform = CATransform3DMakeScale(964.534/w, 1675.8/h, 1)
let startPoint: CGPoint = CGPoint(x: 1, y: 0)
let endPoint: CGPoint = CGPoint(x: -2.2, y: 1.4)
gradientLayer.startPoint = startPoint
gradientLayer.endPoint = endPoint
if let frame = frame {
gradientLayer.frame = frame
}
return gradientLayer
}
问题#1:有没有更简单的方法来获得径向渐变? 或者 问题#2:我是否应该让 UI 设计师隔离我需要作为背景的 svg 部分,然后硬着头皮在每个需要它的 uiviewcontroller(30+ 屏幕)中添加 UIImageView 作为背景?
也许有一些直接的方法可以将 CSS 百分比映射到位置数组?
UPD:Youtube 及时向我推荐 https://www.youtube.com/watch?v=I4gUvhG7uFU 让我少讨厌 css 一点。但免责声明仍然有效,我不懂 css,可以在这里求助。
指定径向渐变方向的枚举
enum RadialGradientDirection {
case centerToEdge
case edgeToCenter
}
扩展 UIView 以添加径向渐变功能
extension UIView {
func applyRadialGradient(colors: [UIColor], direction: RadialGradientDirection, radius: CGFloat? = nil) {
let gradientLayer = RadialGradientLayer()
gradientLayer.colors = colors.map { $0.cgColor }
// Define the center and the radius for the gradient
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let endRadius = radius ?? max(bounds.width, bounds.height) / 2
switch direction {
case .centerToEdge:
gradientLayer.startCenter = center
gradientLayer.endCenter = center
gradientLayer.startRadius = 0
gradientLayer.endRadius = endRadius
case .edgeToCenter:
gradientLayer.startCenter = center
gradientLayer.endCenter = center
gradientLayer.startRadius = endRadius
gradientLayer.endRadius = 0
}
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
func removeRadialGradient() {
layer.sublayers?
.filter { $0 is RadialGradientLayer } // Find all radial gradient layers
.forEach { $0.removeFromSuperlayer() } // Remove them
}
}
自定义径向渐变层
class RadialGradientLayer: CALayer {
var colors: [CGColor] = []
var startCenter: CGPoint = .zero
var endCenter: CGPoint = .zero
var startRadius: CGFloat = 0
var endRadius: CGFloat = 0
override func draw(in ctx: CGContext) {
ctx.saveGState()
// Create a gradient with the provided colors
guard let gradient = CGGradient(colorsSpace: nil, colors: colors as CFArray, locations: nil) else { return }
// Draw the radial gradient
ctx.drawRadialGradient(
gradient,
startCenter: startCenter,
startRadius: startRadius,
endCenter: endCenter,
endRadius: endRadius,
options: .drawsBeforeStartLocation
)
ctx.restoreGState()
}
}