iOS动画和特效(二)UIKit力学行为

来源:互联网 发布:淘宝怎样找在线客服 编辑:程序博客网 时间:2024/05/15 13:36

iOS动画和特效(二)UIKit力学行为

UIKit Dynamics是UIKit的动力交互体系,比如重力,铰链连接,碰撞,悬挂等物理效果,它将2D物理引擎引入了人UIKit,它能使原本的动画和交互效果更加符合物理规律,当然动画效果也更逼真。

先看一个简单的demo view添加重力效果

    //自由落体    func fall(){        /*给箱子加上重力效果*/        //初始化动画的持有者        let gravityAnimator =  UIDynamicAnimator(referenceView: view)        //初始化重力行为        let gravityBehavior = UIGravityBehavior(items: [box])        //添加重力行为        gravityAnimator.addBehavior(gravityBehavior)        //需要保持变量        self.animator = gravityAnimator    }

UIKit Dynamics基础

为了实现动力行为UI,我们必须先了解四个对象

  • UIDynamicItem:用来描述一个力学物体的状态,其实就是实现了UIDynamicItem委托的对象,或者抽象为有面积有旋转的质点;
  • UIDynamicBehavior:动力行为的描述,如例子中的重力行为
  • UIDynamicAnimator:动力行为(UIDynamicBehavior)的容器,添加到容器内的行为将发挥作用。
  • ReferenceView:力学参考对象,就是对象在哪个view中会产生响应的力学行为,例子中let gravityAnimator = UIDynamicAnimator(referenceView: view) 对象产生力学作用的区域是 self.view

场见的力学行为有这么几种

  • UIAttachmentBehavior:连接行为
  • UICollisionBehavior:碰撞行为
  • UIGravityBehavior:重力行为
  • UIPushBehavior:推力行为
  • UISnapBehavior:不知道怎么翻译,实际效果类似吸引力

重力+碰撞

前面的demo中box会一直落下,我们给demo改一改,变成落到地下后就停止

        //自由落在地板上        func fallDown(){            //初始化动画的持有者            let animator =  UIDynamicAnimator(referenceView: view)            //初始化重力行为            let gravityBehavior = UIGravityBehavior(items: [box])            //添加重力行为            animator.addBehavior(gravityBehavior)            //初始化碰撞行为            let collisionBehavior = UICollisionBehavior(items: [box])            //指定边界为参考系的边界            collisionBehavior.translatesReferenceBoundsIntoBoundary = true            animator.addBehavior(collisionBehavior)            //需要保持变量            self.animator = animator        }

//还可以添加更为复杂边界//Bezier边界collisionBehavior.addBoundaryWithIdentifier(<identifier: NSCopying NSCopying>, forPath: <UIBezierPath>)//线边界collisionBehavior.addBoundaryWithIdentifier(<#identifier: NSCopying NSCopying>, fromPoint: <CGPoint>, toPoint: <GPoint>)

重力+附着力

这次把box钉在点200,200位置

UIAttachmentBehavior是连接行为,要把box钉在某一位置,就给他添加连接行为即可

    //把box钉在 x: 200, y: 200 位置    func pin(){        //初始化动画的持有者        let animator =  UIDynamicAnimator(referenceView: view)        //初始化重力行为        let gravityBehavior = UIGravityBehavior(items: [box])        //添加重力行为        animator.addBehavior(gravityBehavior)        //初始化连接行为        let attachmentBehavior = UIAttachmentBehavior(item: box, attachedToAnchor: CGPoint(x: 200, y: 200))        //把点画出来        let point = UIImageView(image: UIImage(named: "AttachmentPoint_Mask"))        point.frame = CGRect(x: 200, y: 200, width: 10, height: 10)        view.addSubview(point)        //设置行为        animator.addBehavior(attachmentBehavior)        //需要保持变量        self.animator = animator    }

重力+推力

这次利用推力,把箱子往右上角方向推一下,把箱子丢出去

    //丢箱子    func throwBox(){        //重新设置box的位置        box.hidden = true        box.frame = CGRect(x: 0, y: 400, width: 50, height: 50)        box.hidden = false        //初始化动画的持有者        let animator =  UIDynamicAnimator(referenceView: view)        //初始化重力行为        let gravityBehavior = UIGravityBehavior(items: [box])        //添加重力行为        animator.addBehavior(gravityBehavior)        //初始化推力行为     Continuous:持续给力 Instantaneous:瞬间给力        let pushBehavior = UIPushBehavior(items: [box], mode: .Instantaneous)        //推力速度        pushBehavior.magnitude = 2        //推力方向        pushBehavior.angle = pointToAngle(CGPoint(x: 500, y: -300))        //设置行为        animator.addBehavior(pushBehavior)        //设置边界        let collisionBehavior = UICollisionBehavior(items: [box])        collisionBehavior.translatesReferenceBoundsIntoBoundary = true        animator.addBehavior(collisionBehavior)        //需要保持变量        self.animator = animator    }    //根据给定点和view中心点计算角度    func pointToAngle(p:CGPoint)->CGFloat{        let o: CGPoint = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds))        let angle: CGFloat = atan2(p.y - o.y, p.x - o.x)        return angle    }

重力+黑洞吸引

让自由落下的箱子被黑洞吸引吧!

//黑洞func blockHole(){    //把黑洞画出来    let point = UIImageView(image: UIImage(named: "blackhole"))    point.frame = CGRect(x: 300, y: 140, width: 50, height: 50)    view.addSubview(point)    //初始化动画的持有者    let animator =  UIDynamicAnimator(referenceView: view)    //初始化重力行为    let gravityBehavior = UIGravityBehavior(items: [box])    //添加重力行为    animator.addBehavior(gravityBehavior)    //需要保持变量    self.animator = animator    //0.5秒后启动黑洞    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(500 * NSEC_PER_MSEC)), dispatch_get_main_queue()) { () -> Void in        NSLog("black hole !!!")        let snapBehavior = UISnapBehavior(item: self.box, snapToPoint: CGPoint(x: 300, y: 140))        snapBehavior.damping = 50 //阻尼        self.animator.addBehavior(snapBehavior)    }}

自定义力学行为,合成多个力学行为的效果

让自由落下的箱子被黑洞吸引吧!

定义一个行为类,给行为添加重力和吸力子行为

    class GravityAndSnapBehavior:UIDynamicBehavior {        init(view:UIView) {            var point:CGPoint!            super.init()            let gravityBehavior = UIGravityBehavior(items: [view])            let snapBehavior = UISnapBehavior(item: view, snapToPoint: CGPoint(x: 300, y: 140))            self.addChildBehavior(gravityBehavior)            point =  CGPoint(x: 100 , y: 100)            self.addChildBehavior(snapBehavior)            //可以监听每一个步骤,然后自己对行为加自定义的影响和作用            self.action = {                NSLog("step")//                view.layer.position = CGPoint(x: point.x++, y: point.y++)      }

黑洞+使用自定义的合成行为

    class GravityAndSnapBehavior:UIDynamicBehavior {        init(view:UIView) {            //把黑洞画出来            let blackhole = UIImageView(image: UIImage(named: "blackhole"))            blackhole.frame = CGRect(x: 300, y: 140, width: 50, height: 50)            view.addSubview(blackhole)            //初始化动画的持有者            let animator =  UIDynamicAnimator(referenceView: view)            //初始化合成行为            let gravityAndSnapBehavior = GravityAndSnapBehavior(view: box)            //添加重力行为            animator.addBehavior(gravityAndSnapBehavior)            //需要保持变量            self.animator = animator      }

指定注意的是UIDynamBehavior中的action属性,这个属性会再每次view改变时候出发,因此你可以根据自己需要,添加自己的特殊行为


0 0
原创粉丝点击