如何解决我无法将 UIBezierPath 添加到 CAEmitterCell 的内容变量
我无法将使用 UIBezierPath 绘制的图标添加到 CAEmitterCell。请问图标是不是画出来的?当我运行应用程序时,ShapeView 不起作用。但是,您可能会发现 ShapeView 在您正常使用时可以正常工作。
那么我有机会将 UIBezierPath 转换为图像吗?
不转图片真的可以吗?
使用
struct GameView: View {
....
let playerBounds = UIBezierPath.calculateBounds(paths: [.none,.playerX,.playerO])
var body: some View {
ZStack {
ParticleEffectView(particleImages: [ShapeView(bezier: .playerX,pathBounds: playerBounds),ShapeView(bezier: .playerO,pathBounds: playerBounds)])
....
}
}
}
形状视图
struct ShapeView: Shape {
let bezier: UIBezierPath
let pathBounds: CGRect
func path(in rect: CGRect) -> Path {
let pointScale = (rect.width >= rect.height) ? max(pathBounds.height,pathBounds.width) : min(pathBounds.height,pathBounds.width)
let pointTransform = CGAffineTransform(scaleX: 1/pointScale,y: 1/pointScale)
let path = Path(bezier.cgPath).applying(pointTransform)
let multiplier = min(rect.width,rect.height)
let transform = CGAffineTransform(scaleX: multiplier,y: multiplier)
return path.applying(transform)
}
}
UIBezier 路径
extension UIBezierPath {
static func calculateBounds(paths: [UIBezierPath]) -> CGRect {
let myPaths = UIBezierPath()
for path in paths {
myPaths.append(path)
}
return (myPaths.bounds)
}
static var playerX: UIBezierPath {
let shape = UIBezierPath()
shape.move(to: CGPoint(x: 48.04,y: 33.28))
shape.addLine(to: CGPoint(x: 62.04,y: 19.28))
shape.addCurve(to: CGPoint(x: 62.04,y: 3.96),controlPoint1: CGPoint(x: 66.28,y: 15.05),controlPoint2: CGPoint(x: 66.28,y: 8.19))
shape.addCurve(to: CGPoint(x: 46.72,controlPoint1: CGPoint(x: 57.81,y: -0.27),controlPoint2: CGPoint(x: 50.96,y: -0.27))
shape.addLine(to: CGPoint(x: 32.72,y: 17.96))
shape.addLine(to: CGPoint(x: 18.71,y: 3.96))
shape.addCurve(to: CGPoint(x: 3.39,controlPoint1: CGPoint(x: 14.48,controlPoint2: CGPoint(x: 7.62,y: -0.27))
shape.addCurve(to: CGPoint(x: 3.39,y: 19.28),controlPoint1: CGPoint(x: -0.84,y: 8.18),controlPoint2: CGPoint(x: -0.84,y: 15.05))
shape.addLine(to: CGPoint(x: 17.4,y: 33.28))
shape.addLine(to: CGPoint(x: 3.39,y: 47.29))
shape.addCurve(to: CGPoint(x: 3.39,y: 62.61),y: 51.52),y: 58.38))
shape.addCurve(to: CGPoint(x: 18.71,controlPoint1: CGPoint(x: 7.62,y: 66.84),controlPoint2: CGPoint(x: 14.48,y: 66.84))
shape.addLine(to: CGPoint(x: 32.72,y: 48.6))
shape.addLine(to: CGPoint(x: 46.72,y: 62.61))
shape.addCurve(to: CGPoint(x: 62.04,controlPoint1: CGPoint(x: 50.96,controlPoint2: CGPoint(x: 57.81,y: 66.84))
shape.addCurve(to: CGPoint(x: 62.04,y: 47.29),y: 58.38),y: 51.52))
shape.addLine(to: CGPoint(x: 48.04,y: 33.28))
shape.close()
return shape
}
static var playerO: UIBezierPath {
let shape = UIBezierPath()
shape.move(to: CGPoint(x: 32.5,y: 0))
shape.addCurve(to: CGPoint(x: 0,y: 32.5),controlPoint1: CGPoint(x: 14.55,y: 0),controlPoint2: CGPoint(x: 0,y: 14.55))
shape.addCurve(to: CGPoint(x: 32.5,y: 65),controlPoint1: CGPoint(x: 0,y: 50.45),controlPoint2: CGPoint(x: 14.55,y: 65))
shape.addCurve(to: CGPoint(x: 65,controlPoint1: CGPoint(x: 50.45,controlPoint2: CGPoint(x: 65,y: 50.45))
shape.addCurve(to: CGPoint(x: 32.5,controlPoint1: CGPoint(x: 65,y: 14.55),controlPoint2: CGPoint(x: 50.45,y: 0))
shape.close()
shape.move(to: CGPoint(x: 32.01,y: 49.24))
shape.addCurve(to: CGPoint(x: 15.76,y: 32.99),controlPoint1: CGPoint(x: 23.03,y: 49.24),controlPoint2: CGPoint(x: 15.76,y: 41.97))
shape.addCurve(to: CGPoint(x: 32.01,y: 16.74),controlPoint1: CGPoint(x: 15.76,y: 24.02),controlPoint2: CGPoint(x: 23.03,y: 16.74))
shape.addCurve(to: CGPoint(x: 48.26,controlPoint1: CGPoint(x: 40.98,controlPoint2: CGPoint(x: 48.26,y: 24.02))
shape.addCurve(to: CGPoint(x: 32.01,controlPoint1: CGPoint(x: 48.26,y: 41.97),controlPoint2: CGPoint(x: 40.98,y: 49.24))
shape.close()
return shape
}
static var none: UIBezierPath {
let shape = UIBezierPath()
return shape
}
}
粒子效果视图
struct ParticleEffectView: UIViewRepresentable {
var particleImages: [ShapeView]
func makeUIView(context: Context) -> UIView {
let host = UIView(frame: CGRect(x: 0.0,y: 0.0,width: UIScreen.main.bounds.width,height: UIScreen.main.bounds.height))
let particlesLayer = CAEmitterLayer()
particlesLayer.frame = CGRect(x: 0.0,height: UIScreen.main.bounds.height)
host.layer.insertSublayer(particlesLayer,at: 0)
host.layer.masksToBounds = true
host.insetsLayoutMarginsFromSafeArea = false
particlesLayer.backgroundColor = .none
particlesLayer.emitterShape = .circle
particlesLayer.emitterPosition = CGPoint(x: 509.4,y: 707.7)
particlesLayer.emitterSize = CGSize(width: 1648.0,height: 1112.0)
particlesLayer.emitterMode = .outline
particlesLayer.renderMode = .backToFront
particlesLayer.emitterCells = prepareParticeCell(particles: particleImages)
return host
}
func prepareParticeCell(particles: [ShapeView]) -> [CAEmitterCell] {
var arrayParticleCell: [CAEmitterCell] = [CAEmitterCell]()
for particleItem in particles {
let particleCell: CAEmitterCell = CAEmitterCell()
particleCell.contents = particleItem
particleCell.name = "XO"
particleCell.birthRate = 1
particleCell.lifetime = 74.5
particleCell.veLocityRange = 0.0
particleCell.veLocity = 79.0
particleCell.xacceleration = 0.0
particleCell.yacceleration = 0.0
particleCell.emissionLatitude = 1*6.0 * (.pi / 180)
particleCell.emissionLongitude = -105.0 * (.pi / 180)
particleCell.emissionRange = 360.0 * (.pi / 180.0)
particleCell.spin = -65.6 * (.pi / 180.0)
particleCell.spinRange = 314.2 * (.pi / 180.0)
particleCell.scale = 0.010
particleCell.scaleRange = 0.01
particleCell.scaleSpeed = 0.02
particleCell.alpharange = 0.0
particleCell.alphaSpeed = 0.47
particleCell.color = UIColor(red: 255.0/255.0,green: 255.0/255.0,blue: 255.0/255.0,alpha: 1.0).cgColor
arrayParticleCell.append(particleCell)
}
return arrayParticleCell
}
func updateUIView(_ uiView: UIView,context: Context) {
uiView.insetsLayoutMarginsFromSafeArea = false
}
}
解决方法
当你说
particleCell.contents = particleItem
没有编译时错误,但在运行时也没有任何反应。那是因为发射器单元 contents
唯一可以是 CGImage(参见 documentation)——而 ShapeView,很明显,不是 CGImage。将 contents
设置为 CGImage 以外的任何其他内容不是错误但无效,并且找出问题所在可能需要很长时间。我经常向 Apple 抱怨这个问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。