簡體   English   中英

我無法將 UIBezierPath 添加到 CAEmitterCell 的內容變量

[英]I can't add UIBezierPath to CAEmitterCell's contents variable

我無法將使用 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, 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 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。 contents設置為除 CGImage 之外的任何其他內容不是錯誤,而是無效,並且找出問題所在可能需要很長時間。 我經常向蘋果抱怨這件事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM