2

我正在创建一个 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高度不起作用,因为如果我改变上面emitterSize的宽度,我可以看到宽度正确改变!无论我为身高赋予什么价值......它都会被忽略。

和 CAEmitterCells

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

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

4

2 回答 2

3

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 是一个一秒钟的循环。)

于 2018-03-15T17:19:45.530 回答
0

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

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

于 2018-02-26T20:06:56.130 回答