Swift 我能';t将UIBezierPath添加到CAEmitterCell';s内容变量

Swift 我能';t将UIBezierPath添加到CAEmitterCell';s内容变量,swift,swiftui,uibezierpath,caemitterlayer,Swift,Swiftui,Uibezierpath,Caemitterlayer,我无法将我用UIBezierPath绘制的图标添加到CAEmitterCell。我想知道图标是否没有画出来?运行应用程序时,ShapeView不工作。但是,当您正常使用ShapeView时,您可能会发现它可以正常工作 那么我有机会将UIBezierPath转换为图像吗 在不转换为图像的情况下,它真的可以完成吗 使用 struct GameView: View { .... let playerBounds = UIBezierPath.calculateBounds(p

我无法将我用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)
    }
}
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, y: 0.0, width: UIScreen.main.bounds.width, 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
        
    }
}
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, y: 3.96), 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, y: 3.96), controlPoint1: CGPoint(x: 14.48, y: -0.27), 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), controlPoint1: CGPoint(x: -0.84, y: 51.52), controlPoint2: CGPoint(x: -0.84, y: 58.38))
        shape.addCurve(to: CGPoint(x: 18.71, y: 62.61), 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, y: 62.61), controlPoint1: CGPoint(x: 50.96, y: 66.84), controlPoint2: CGPoint(x: 57.81, y: 66.84))
        shape.addCurve(to: CGPoint(x: 62.04, y: 47.29), controlPoint1: CGPoint(x: 66.28, y: 58.38), controlPoint2: CGPoint(x: 66.28, 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, y: 32.5), controlPoint1: CGPoint(x: 50.45, y: 65), controlPoint2: CGPoint(x: 65, y: 50.45))
        shape.addCurve(to: CGPoint(x: 32.5, y: 0), 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, y: 32.99), controlPoint1: CGPoint(x: 40.98, y: 16.74), controlPoint2: CGPoint(x: 48.26, y: 24.02))
        shape.addCurve(to: CGPoint(x: 32.01, y: 49.24), 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 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)
    }
}
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, y: 0.0, width: UIScreen.main.bounds.width, 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(参见),而ShapeView显然不是CGImage。将
内容
设置为CGImage以外的任何内容都不是错误,而是无效的,并且找出问题所在可能需要很长时间。我经常向苹果抱怨这一点。

我可以将UIBezierPath转换为图像吗?您可以将UIBezierPath绘制到图像图形上下文中并提取图像。但在我看来,这是一个不同的问题。