我想在我的代码中为某个事件举行庆祝活动。所以我从GitHub(https://github.com/sudeepag/SAConfettiView)采取了一个快速的纸屑叠加,并试图在我的项目中使用它。基本上,如果发生某个事件,它会启动NSTimer。我还定义了showAlert
和dismissAlert
,用于在UIAlertView上弹出无按钮消息,说Congrats!
。当计时器第一次勾选confettitime
(从0开始)时,它开始五彩纸屑覆盖(成功)。然后,在第三个刻度,它激活showAlert
。弹出消息。它在计时器的第七个刻度处成功解除dismissAlert
。但我不能让隐藏/五彩纸屑消失。根据GitHub项目中的说明,我打电话给confettiView.stopConfetti()
让它停下来!但它只是继续显示五彩纸屑,冻结我的UI。我试过删除通知(没有效果),显着改变五彩纸屑代码(没有效果),我只是找不到隐藏叠加五彩纸屑视图的方法。
我按照GitHub项目中的Manual Installation
指示,将图像资源和SAConfettiView.swift
添加到我的Swift XCode项目中。我不得不更改几个代码位,因为它们崩溃了(就像这条评论说:https://github.com/sudeepag/SAConfettiView/pull/6),所以也许这会影响它?
这是SAConfettiView的代码,它是GitHub项目的产物:
import UIKit
import QuartzCore
public class SAConfettiView: UIView {
public enum ConfettiType {
case Confetti
case Triangle
case Star
case Diamond
case Image(UIImage)
}
var emitter: CAEmitterLayer!
public var colors: [UIColor]!
public var intensity: Float!
public var type: ConfettiType!
private var active :Bool!
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
public override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup() {
colors = [UIColor(red:0.95, green:0.40, blue:0.27, alpha:1.0),
UIColor(red:1.00, green:0.78, blue:0.36, alpha:1.0),
UIColor(red:0.48, green:0.78, blue:0.64, alpha:1.0),
UIColor(red:0.30, green:0.76, blue:0.85, alpha:1.0),
UIColor(red:0.58, green:0.39, blue:0.55, alpha:1.0)]
intensity = 0.5
type = .Confetti
active = false
}
public func startConfetti() {
emitter = CAEmitterLayer()
emitter.emitterPosition = CGPoint(x: frame.size.width / 2.0, y: 0)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: frame.size.width, height: 1)
var cells = [CAEmitterCell]()
for color in colors {
cells.append(confettiWithColor(color))
}
emitter.emitterCells = cells
layer.addSublayer(emitter)
active = true
}
public func stopConfetti() {
emitter?.birthRate = 0
active = false
}
func imageForType(type: ConfettiType) -> UIImage? {
print(type)
var fileName: String!
switch type {
case .Confetti:
fileName = "Confetti"
case .Triangle:
fileName = "triangle"
case .Star:
fileName = "star"
case .Diamond:
fileName = "diamond"
case let .Image(customImage):
return customImage
}
print(type)
return UIImage(imageLiteral: "\(type)")
}
func confettiWithColor(color: UIColor) -> CAEmitterCell {
let confetti = CAEmitterCell()
confetti.birthRate = 6.0 * intensity
confetti.lifetime = 14.0 * intensity
confetti.lifetimeRange = 0
confetti.color = color.CGColor
confetti.velocity = CGFloat(350.0 * intensity)
confetti.velocityRange = CGFloat(80.0 * intensity)
confetti.emissionLongitude = CGFloat(M_PI)
confetti.emissionRange = CGFloat(M_PI_4)
confetti.spin = CGFloat(3.5 * intensity)
confetti.spinRange = CGFloat(4.0 * intensity)
confetti.scaleRange = CGFloat(intensity)
confetti.scaleSpeed = CGFloat(-0.1 * intensity)
confetti.contents = imageForType(type)!.CGImage
return confetti
}
public func isActive() -> Bool {
return self.active
}
}
这是我项目中的相关代码,我称之为五彩纸屑:
var confettitimer = NSTimer()
var confettitime = 0
var alreadyconfettied = false
func confetti() {
confettitime++
let confettiView = SAConfettiView(frame: self.view.bounds)
self.view.addSubview(confettiView)
if confettitime == 1 {
confettiView.type = .Confetti
confettiView.startConfetti()
alreadyconfettied = true
}
if confettitime == 3 {
showAlert2()
}
if confettitime == 7 {
dismissAlert2()
}
if confettitime == 10 {
confettiView.stopConfetti()
lp.confettitimer.invalidate()
lp.confettitime = 0
}
}
if event == true && alreadyconfettied == false {
confettitimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "confetti", userInfo: nil, repeats: true)
alreadyconfettied = true
}
很抱歉所有的代码!如果你能告诉我如何让这个五彩纸屑叠加停下来会非常有用!
更新1(仍未解决):
所以我需要让ConfettiView创建在与.startConfetti()
和.stopConfetti()
相同的功能中进行!使用计时器无法做到这一点,因为当两者都在同一个函数内时,计时器无法调用函数(参见此处:https://stackoverflow.com/a/25839597/5700898)。现在,当某个事件发生时,它会调用confetti()函数......
func confetti() { // called once and only once when the event is triggered.
let confettiView = SAConfettiView(frame: self.view.bounds)
self.view.addSubview(confettiView)
var confettitimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "confettisub", userInfo: nil, repeats: true)
func confettisubfunction() {
lp.confettitime++
print(lp.confettitime)
if confettitime == 1 {
confettiView.type = .Confetti
confettiView.startConfetti()
alreadyconfettied = true
}
if confettitime == 3 {
showAlert2()
}
if confettitime == 7 {
dismissAlert2()
}
if confettitime == 10 {
confettiView.stopConfetti()
confettitimer.invalidate()
confettitime = 0
}
}
}
但是,正如我上面所说,这引发了灾难性的错误。基本上,这种设置是不可能的,因为视图的声明不能与我用.startConfetti()
调用它的函数相同,并且它不能是全局变量/声明:
- 如果我在let confettiView = SAConfettiView(frame: self.view.bounds)
self.view.addSubview(confettiView)
之前class ViewController: UIViewController {
,那么它不知道自己是什么,并给出错误“顶层不允许表达”。
- 如果我使用相同的代码在视图控制器的声明中定义我的Confetti UIView ,它会显示“预期声明”。
那么我怎样才能解决这个问题,并在某个事件发生时让五彩纸屑下雨,如何在一个计时器的帮助下停止所述五彩纸屑(或者任何可行的东西?)
提前感谢您的帮助!
更新2(差不多已解决):
在我的全球范围内,我基本上是这样做的,每次庆祝时我都会致电initconfetti()
一次。这让我只有一个五彩纸屑视图,我打电话给startConfetti()
和stopConfetti()
,让我实际上再次停止五彩纸屑!!
var confettiView = SAConfettiView()
func initconfetti() {
confettiView = SAConfettiView(frame: self.view.bounds)
self.view.addSubview(confettiView)
}
现在我有一个问题:我无法回到点击原始视图(我的视图控制器)!我如何杀死五彩纸屑视图?也许我的界限是0,0?我必须努力解决这个问题(我还是喜欢一些建议)。
当五彩纸屑结束时,我正在调用这一系列命令(我真的不知道它们的含义):
confettiView.removeFromSuperview()
confettiView = SAConfettiView(frame: CGRect(
origin: CGPoint(x: 0, y: 0),
size: CGSize(width: 0, height: 0)))
view.becomeFirstResponder()
self.view.becomeFirstResponder()
但是我的View Controller仍然没有响应任何地方的点击,没有任何事情发生!怎么办?是否有一个功能可以让我的旧视图再次出现在前台?
谢谢!
答案 0 :(得分:3)
每次输入confetti
功能时,您都会创建一个新SAConfettiView
并将其添加到控制器的视图中。我没有遵循所有if
声明,但我认为可以肯定地说,您正在调用的stopConfetti
视图与您用于startConfetti
的视图不同。< / p>
我建议在计时器例程之外创建视图,并仅通过计时器控制它。
答案 1 :(得分:0)
查看以下关于所有内容的其他答案的评论,并在下面了解如何仅创建一次子视图:
首先,请务必只拨打一次!在全局范围内执行此操作,就在整个class ViewController : UIViewController {
之下。
var confettiView = SAConfettiView()
func initconfetti() {
confettiView = SAConfettiView(frame: self.view.bounds)
self.view.addSubview(confettiView)
}
func deinitconfetti() {
confettiView.removeFromSuperview()
}
这就是全部。现在在NSTimer的帮助下调用它们。