提问人:batman 提问时间:9/5/2023 更新时间:9/5/2023 访问量:40
CAEmitterLayer 未从视图中心发射粒子
CAEmitterLayer not emitting particles from view center
问:
我有以下 BoardView,它包装在 UIViewRepresentable 中,并显示在 SwiftUI VStack 中。它基本上是 UIView 磁贴的 3x3 网格。我试图实现的是,当在视图上调用 showWinningAnimation 时,每个图块都应该以非常短的随机时间间隔从图块中心爆炸成五彩纸屑状粒子,向各个方向投射粒子,并且图块应该消失。爆炸应该类似于鞭炮,这是我最好的说法。我有以下代码,但似乎爆炸发生在不同的位置,而不是从每个瓷砖的中心点开始,并且投影也不像烟花。还有没有更好的方法可以使瓷砖在爆炸时消失?目前,我将 alpha 设置为 0.0,但我对结果不太满意。
class BoardView: UIView {
private let tilesPerRow = 3
private let tileSize = CGSize(width: 100, height: 100)
private let tileContainerView = UIView()
private let tileColors: [UIColor] = [.red, .blue, .orange, .yellow, .green, .white]
override func layoutSubviews() {
tileContainerView.center = self.center
}
func addTiles() {
tileContainerView.frame = CGRect(origin: .zero, size: CGSize(width: tileSize.width * CGFloat(tilesPerRow),
height: tileSize.height * CGFloat(tilesPerRow)))
for row in 0..<tilesPerRow {
for col in 0..<tilesPerRow {
let frame = CGRect(
x: CGFloat(col) * tileSize.width,
y: CGFloat(row) * tileSize.width,
width: tileSize.width,
height: tileSize.height
)
let tileView = UIView(frame: frame)
tileView.backgroundColor = tileColors.randomElement()
tileContainerView.addSubview(tileView)
}
}
addSubview(tileContainerView)
tileContainerView.center = self.center
}
func showWinningAnimation() {
for subview in tileContainerView.subviews {
let confettiEmitter = CAEmitterLayer()
confettiEmitter.emitterShape = .rectangle
confettiEmitter.emitterPosition = subview.center
confettiEmitter.emitterSize = subview.bounds.size
var confettiCells = [CAEmitterCell]()
for color in self.tileColors {
confettiCells.append(self.confettiWithColor(color: color))
}
confettiEmitter.emitterCells = confettiCells
subview.layer.addSublayer(confettiEmitter)
UIView.animate(withDuration: .random(in: 0...1)) {
subview.alpha = 0
} completion: { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
confettiEmitter.removeFromSuperlayer()
}
}
}
}
private func confettiWithColor(color: UIColor) -> CAEmitterCell {
let confetti = CAEmitterCell()
confetti.color = color.cgColor
confetti.birthRate = 5.0
confetti.lifetime = 5.0
confetti.velocity = 150
confetti.emissionLongitude = CGFloat.pi
confetti.emissionRange = CGFloat.pi * 2
confetti.spin = 3.5
confetti.spinRange = 1
confetti.scaleRange = 0.5
confetti.scaleSpeed = -0.1
confetti.contents = UIImage.imageWithColor(.white, size: CGSize(width: 5, height: 5)).cgImage
return confetti
}
}
extension UIImage {
static func imageWithColor(_ color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
答: 暂无答案
评论