Swift3.0 UIDynamic 仿真器, 物理引擎

654 阅读3分钟
原文链接: www.jianshu.com

在OC上使用UIDynamic和Swift3.0 差不多一样的方法,可能UIDynamic已经够简洁,但是要写出棒棒哒的效果还是需要很多的组合行为才能实现。

//声明一个物理仿真器
var dynamicAnimator = UIDynamicAnimator()
//声明一个数组里面全是imageView, 做仿真运动时可以叫做物体,便于理解
var imageArray = Array<UIImageView>()

// MARK -- image  这个iamgeV单独做阻尼运动
let imageV: UIImageView = {
    let ima = UIImageView()
    ima.frame = CGRect(x: 0, y: 200, width: 40, height: 40)
    ima.layer.cornerRadius = 20
    ima.backgroundColor = UIColor.gray
    ima.layer.masksToBounds = true
    return ima
}()
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = UIColor.black
    //初始话物理仿真器,并且设置作用范围是整个视图
    dynamicAnimator = UIDynamicAnimator(referenceView: self.view)

    //创建8个圆形物体,并且添加在数组上
    for index in 0...7 {
        let imageV = UIImageView()
        imageV.frame = CGRect(x: (index % 4) * 70, y: (index / 4) * 70 + 64, width: 60, height: 60)
        self.view.addSubview(imageV)
        imageV.backgroundColor = index / 4 == 0 ? UIColor.red : UIColor.green
        imageV.layer.cornerRadius = 30
        imageV.layer.masksToBounds = true
        imageArray.append(imageV)
    }
    self.view.addSubview(imageV)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    //这里你可以一个一个的尝试行为,找到自己要实现的效果

    // 声明一个重力行为,加在物体上,这里Items:后面是一个数组, 可以使用[imageV]单个物体,也可想我一样使用数组,下面的items都一样
    let graviteImage = UIGravityBehavior(items: imageArray)
    //添加一个重力加速度为10的重力
    graviteImage.magnitude = 8
    //添加一个矢量方向, dx:1, dy: 1  表示45度方向 就是x为1,y为1,这个方向就是他们的四边形的对角线方向
    graviteImage.gravityDirection = CGVector.init(dx: 1, dy: 1)
    //将重力行为加在物理仿真器上
    dynamicAnimator.addBehavior(graviteImage)

    //声明一个碰撞行为,加在物体上
    let  collison = UICollisionBehavior(items: imageArray)
    //这个约束是在这个物理仿真器所在的view的边界是否形成碰撞边界
    collison.translatesReferenceBoundsIntoBoundary = true
    //碰撞行为有一个代理,里面的方法是开始行为,结束行为等等时刻
    collison.collisionDelegate = self
    //将碰撞行为加在仿真器上
    dynamicAnimator.addBehavior(collison)

    //此时我们的物体没有物理属性,碰撞后都不会回弹不是很真实
    //所以给物体添加属性
    let imageVLetter = UIDynamicItemBehavior(items: imageArray)
    //物体弹性0-1  0没有弹性,1 表示可以回弹到初始位置,但是我们物体上还有重力作用所以是不会回到初始位置的
    imageVLetter.elasticity = 1
    //密度 0~
    imageVLetter.density = 3
    //阻力
    imageVLetter.resistance = 0.5
    //摩擦力  0~
    imageVLetter.friction = 0.3
    //角阻力
    imageVLetter.angularResistance = 0.2
    //将属性加在仿真器上
    dynamicAnimator.addBehavior(imageVLetter)

    //最后我们添加一下吸附行为,这个行为只能添加在一个物体上,属性也只有一个阻尼   snapTo:这个点就是吸附点,力量来自这里,阻尼就是牵引物体过来的力量,反弹
    let snapBeheavior = UISnapBehavior(item: imageV, snapTo: CGPoint(x: 160, y: 400))
    //阻尼,
    snapBeheavior.damping = 0.1
    //将吸附行为加在仿真器上
    dynamicAnimator.addBehavior(snapBeheavior)
    //上面所以的行为都可以删除 
    // dynamicAnimator.removeBehavior(snapBheavior)
    //dynamicAnimator.removeBehavior(imageVLetter)
}

     //下面是代理方法   开始,结束
func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint) {
    print("1   beganContactFor")
}
func collisionBehavior(_ behavior: UICollisionBehavior, endedContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?) {
    print("2   endedContactFor")
}

我这里全当抛砖引玉
最后祝大家圣诞快乐!!!