Ios 如何添加';雪一样的';对视图的影响

Ios 如何添加';雪一样的';对视图的影响,ios,uiview,core-graphics,core-animation,Ios,Uiview,Core Graphics,Core Animation,我目前正在制作一个圣诞应用程序,我希望它在屏幕上“下雪” 到目前为止,我有以下代码: 雪。雨燕 import Foundation import UIKit @IBDesignable class Snow:UIView { var viewHeight = CGFloat(0) /* required init(coder aDecoder: NSCoder) { //Initilse UIView super.init(coder:

我目前正在制作一个圣诞应用程序,我希望它在屏幕上“下雪”

到目前为止,我有以下代码:

雪。雨燕

import Foundation
import UIKit

@IBDesignable
class Snow:UIView
{

    var viewHeight = CGFloat(0)
    /*
    required init(coder aDecoder: NSCoder) {
        //Initilse UIView
        super.init(coder: aDecoder)!
    }
    */

    override func drawRect(rect: CGRect) {
        let path = UIBezierPath(ovalInRect: rect)
        UIColor.whiteColor().setFill()
        path.fill()
    }
}
@IBDesignable
class ViewController: UIViewController {

    @IBInspectable var BgColor:UIColor = UIColor.whiteColor()

    var animator: UIDynamicAnimator? = nil;
    var gravity = UIGravityBehavior()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = BgColor
        /*listSubviewsOfView(self.view)*/ /*Not needed to answer this*/
        var snow = Snow(frame: CGRect(x: 0, y: 0, width: 5, height: 5))
        snow.opaque = false
        self.view.addSubview(snow)

        animator = UIDynamicAnimator(referenceView:self.view);
        animator?.addBehavior(gravity)

        gravity.addItem(snow)
        let direction = CGVectorMake(0.0, 1.0)
        gravity.gravityDirection = direction
    }


    /*Not needed to solve this*/
    /*
    func listSubviewsOfView(views: UIView) {
        var index = 0
        let randomNumbers = [Int](1...24).shuffle()
        for view in views.subviews
        {
            if let _ = view.restorationIdentifier
            {
                view.setValue(String(Int(randomNumbers[index])), forKey: "updateText")
                index++
            }
            if index == randomNumbers.count {
                break
            }
        }
    }
    */

}
ViewController.swift

import Foundation
import UIKit

@IBDesignable
class Snow:UIView
{

    var viewHeight = CGFloat(0)
    /*
    required init(coder aDecoder: NSCoder) {
        //Initilse UIView
        super.init(coder: aDecoder)!
    }
    */

    override func drawRect(rect: CGRect) {
        let path = UIBezierPath(ovalInRect: rect)
        UIColor.whiteColor().setFill()
        path.fill()
    }
}
@IBDesignable
class ViewController: UIViewController {

    @IBInspectable var BgColor:UIColor = UIColor.whiteColor()

    var animator: UIDynamicAnimator? = nil;
    var gravity = UIGravityBehavior()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = BgColor
        /*listSubviewsOfView(self.view)*/ /*Not needed to answer this*/
        var snow = Snow(frame: CGRect(x: 0, y: 0, width: 5, height: 5))
        snow.opaque = false
        self.view.addSubview(snow)

        animator = UIDynamicAnimator(referenceView:self.view);
        animator?.addBehavior(gravity)

        gravity.addItem(snow)
        let direction = CGVectorMake(0.0, 1.0)
        gravity.gravityDirection = direction
    }


    /*Not needed to solve this*/
    /*
    func listSubviewsOfView(views: UIView) {
        var index = 0
        let randomNumbers = [Int](1...24).shuffle()
        for view in views.subviews
        {
            if let _ = view.restorationIdentifier
            {
                view.setValue(String(Int(randomNumbers[index])), forKey: "updateText")
                index++
            }
            if index == randomNumbers.count {
                break
            }
        }
    }
    */

}
这就是它目前的样子(在iPhone5模拟器中)

如您所见,
ui视图
落在屏幕底部的速度太快(像砖块而不是雪一样落下)


我怎样才能让“雪”随着风的影响下降得更慢呢?

我会用SKEmitterNode来实现这一点。SpriteKit中还有一个图形编辑器,您可以在其中轻松创建雪效果。这里有一个关于此的简短教程:

如果您当前没有使用SpriteKit,那么您最好使用CAEmitterLayer。请参阅

想法是在修道院视图的顶部添加一个与该视图大小相同的发射器层,顶部有一个发射雪花粒子的线状发射器单元


粒子发射器包括对随机放置和随机运动的支持。(雪花以随机的侧向运动飘落到地面上。)

使用UIKitDynamics的UIGravityBehaviour为对象设置动画。使用UIKitDynamics,您可以非常轻松地创建出色的动画

    snowView = UIView(frame: CGRect(x: 100, y: 100, width: 20, height: 20))
    snowView.backgroundColor = UIColor.blueColor()
    view.addSubview(snowView)

    animator = UIDynamicAnimator(referenceView: view)
    gravity = UIGravityBehavior(items: [snowView])
    animator.addBehavior(gravity)

    animator.addBehavior(collision)

    itemBehaviour = UIDynamicItemBehavior(items: [snowView])
    itemBehaviour.elasticity = 0.7
    animator.addBehavior(itemBehaviour)
请检查此链接以供参考:

我已共享了所有实现。但是你需要flake.png,你可以通过谷歌找到

import UIKit
import QuartzCore

class ViewController: UIViewController {

  var snowView: SnowView!

  override func viewDidLoad() {
    super.viewDidLoad()

    //add the snow effect layer
    snowView = SnowView(frame: CGRect(x: -150, y:-100, width: 300, height: 50))
    let snowClipView = UIView(frame: CGRectOffset(view.frame, 0, 50))
    snowClipView.clipsToBounds = true
    snowClipView.addSubview(snowView)
    view.addSubview(snowClipView)

  }
}


import UIKit
import QuartzCore

class SnowView: UIView {

  override init(frame: CGRect) {
    super.init(frame: frame)

    let emitter = layer as! CAEmitterLayer
    emitter.emitterPosition = CGPoint(x: bounds.size.width / 2, y: 0)
    emitter.emitterSize = bounds.size
    emitter.emitterShape = kCAEmitterLayerRectangle

    let emitterCell = CAEmitterCell()
    emitterCell.contents = UIImage(named: "flake.png")!.CGImage
    emitterCell.birthRate = 200
    emitterCell.lifetime = 3.5
    emitterCell.color = UIColor.whiteColor().CGColor
    emitterCell.redRange = 0.0
    emitterCell.blueRange = 0.1
    emitterCell.greenRange = 0.0
    emitterCell.velocity = 10
    emitterCell.velocityRange = 350
    emitterCell.emissionRange = CGFloat(M_PI_2)
    emitterCell.emissionLongitude = CGFloat(-M_PI)
    emitterCell.yAcceleration = 70
    emitterCell.xAcceleration = 0
    emitterCell.scale = 0.33
    emitterCell.scaleRange = 1.25
    emitterCell.scaleSpeed = -0.25
    emitterCell.alphaRange = 0.5
    emitterCell.alphaSpeed = -0.15

    emitter.emitterCells = [emitterCell]
  }

  required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  override class func layerClass() -> AnyClass {
    return CAEmitterLayer.self
  }

}

我可以在单视图模板中使用它吗?我想可以,但从未尝试过。通常我会创建一个游戏模板:它与一个ViewController和一个故事板一起,您可以在其中添加UIViewElementsPrite工具包不能与UIView混合使用。@RW。是的,它可以
SKView
是一个
UIView
子类,具有关联的
SKScene
。看到这一点,可能会对您有所帮助,但在swift 4.2中运行时会遇到一些问题