【问题标题】:creating a vertical CAEmitterLayer创建垂直 CAEmitterLayer
【发布时间】:2018-03-16 01:19:45
【问题描述】:

我正在创建一个 CAEmitterLayer,它是屏幕的高度,并关闭 -X,因此 CAEmitterCells 从左侧(屏幕外)移动到右上角。

我遇到了一个问题,CAEmitterLayer 的emitterSize height 属性被忽略。这会导致所有单元格从一个点发射,而不是发射器大小的设置。

这是发射器:

emitter.emitterPosition = CGPoint(x: -50, y: (view.frame.height / 2))
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: 2, height: view.frame.height)

我提到了emitterSize height 不起作用,因为如果我改变上述emitterSize 的宽度,我可以看到宽度正常变化!无论我为身高赋予什么价值......它都会被忽略。

还有 CAEmitterCells

cell.birthRate = 10
cell.lifetime = 10
cell.velocity = CGFloat(50)
cell.emissionLongitude = (45 * (.pi/180))

如何将emitterSize 宽度设置为2 磅宽和视图高度?

【问题讨论】:

    标签: swift caemitterlayer caemittercell


    【解决方案1】:

    kCAEmitterLayerLine 始终是一条厚度为零的水平线。仅使用emitterSize.width

    您可以通过将发射器层的变换设置为旋转来垂直使用线条形状。游乐场示例:

    import UIKit
    import PlaygroundSupport
    
    class VerticalEmitterView: UIView {
    
        let emitter = CAEmitterLayer()
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            let bounds = self.bounds
            emitter.position = CGPoint(x: bounds.midX, y: bounds.midY)
            emitter.bounds = CGRect(x: 0, y: 0, width: bounds.size.height, height: bounds.size.width)
            emitter.emitterPosition = CGPoint(x: bounds.width / 2, y: -50)
            emitter.emitterSize = CGSize(width: emitter.bounds.size.width, height: 0)
    
            if emitter.superlayer != self.layer {
                emitter.setAffineTransform(CGAffineTransform(rotationAngle: -.pi / 2))
                emitter.emitterShape = kCAEmitterLayerLine
    
                let cell = CAEmitterCell()
                cell.birthRate = 100
                cell.lifetime = 10
                cell.velocity = 50
                cell.emissionLongitude = .pi
                cell.color = UIColor.red.cgColor
                let particleSize = CGSize(width: 5, height: 5)
                let image = UIGraphicsImageRenderer(size: particleSize).image(actions: { (rc) in
                    UIColor.white.setFill()
                    let gc = UIGraphicsGetCurrentContext()
                    UIBezierPath(ovalIn: CGRect(origin: .zero, size: particleSize)).fill()
                })
                cell.contents = image.cgImage
                emitter.emitterCells = [cell]
    
                layer.addSublayer(emitter)
            }
        }
    
    }
    
    let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
    rootView.backgroundColor = .white
    let emitterView = VerticalEmitterView(frame: rootView.bounds)
    rootView.addSubview(emitterView)
    PlaygroundPage.current.liveView = rootView
    

    结果:

    (不连续是因为这个 GIF 是一个一秒的循环。)

    【讨论】:

      【解决方案2】:

      我遇到了完全相同的问题。查看Apple的文档,看起来如果发射器形状是kCAEmitterLayerLine,它会忽略发射器的高度。

      我发现的不理想的解决方法是使用高度足够大的 kcaEmitterLayerRectangle,以便矩形的一侧是您希望线条所在的位置。

      【讨论】:

      • kCAEmitterLayerRectangle 不是更好的选择吗?
      • 确实有效。但就像@jrturton 提到的那样,你最好使用矩形而不是圆形。
      • @jrturton 是的!矩形起初对我不起作用,但是当正常工作时,是的,它比圆形更好。编辑了答案以包含它。
      猜你喜欢
      • 1970-01-01
      • 2019-02-05
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多