标签:
概念
UIDynamicItem:一个控件想要执行UIDynamicAnimator的动画就必须要继承这个协议。
UIDynamicAnimator:Animator为动态控件提供物理相关的力学和动画,也为这些动画提供了上下文,通过添加Behavier实例来实现想要的动画效果,在以下介绍到的物理力学里面一切动画的源头都是他,也可以说,UIKit的动力学最外层的包装就是它。
ReferenceView:在初始化UIDynamicAnimator的时候有一个叫做referenceView的属性,他是你的参考视图,你的子控件以及子控件的Beahavier就是参考这个视图的坐标的。
UIDynamicBehavior:它可以看做是把一种物理行为封装起来的一个类,一个Behavior实例可以赋予多个动态控件的一个物理行为。
扩展
层次
self.animator = UIDynamicAnimator(referenceView: self.view) var gravity = nil gravity = UIGravityBehavior(items: [littleBall]) self.animator.addBehavior(gravity)
由于本人用的是黑苹果,所以模拟器上会有些闪屏
我们还可以通过magnitude来设置重力加速度,值得一提的是,学过物理的同学应该知道这个吧,不过苹果这里面跟现实还是有些出入的,就像我们现实中g是9.8m/s²,而在UIKit中定义了g是1000 points / second²,换言之,如果一开始我们的速度为0,那么一秒后我们的速度是1000个点/秒
collision = nil
collision = UICollisionBehavior(items: viewArr)
collision.collisionDelegate = self
collision.addBoundaryWithIdentifier("path", fromPoint: CGPointMake(0, self.view.frame.height), toPoint: CGPointMake(self.view.frame.width, self.view.frame.height))
注意:我们可以设置UICollisionBehavior的代理,来监听碰撞的行为,我们可以同translatesReferenceBoundsIntoBoundary这个属性来让我们的参考视图边界作为我们的墙壁,也可以通过这个addBoundaryWithIdentifier来设置我们的墙壁
UIDynamicItemBehavior:设置每个动态控件的自身属性,提供一下属性
我们暂且用这几个物理行为来做一个比较有趣的动画
这个的主要思路如下
重力行为,碰转行为,属性行为
定时器不断加小球,定时器可以选择NSTimer,CADisplayLink以及GCD,前两个不怎么准确,有时还会跳过任务,所以这里我选择了GCD定时器,NSTimer和CADisplayLink底层也是调用GCD定时器的。
当小球消失在屏幕中回收内存,这里我是在碰撞代理方法里面回收,也可以用KVO监听来回收内存,但系统自带的KVO好像不好使,可以试一下Observable-Swift
这个框架,里面很好的利用了Swift的泛型来实现的。
// 添加GCD定时器,比CADisplayLink和NSTimer更精确,受限制较小 let queue:dispatch_queue_t = dispatch_get_main_queue() self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue) let start:dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64((UInt64(1.0) * NSEC_PER_SEC))) let interval:UInt64 = UInt64((UInt64(10.0) * NSEC_PER_SEC)/10) dispatch_source_set_timer(self.timer, start, interval, 0) dispatch_source_set_event_handler(self.timer, { () -> Void in self.addABall() }) dispatch_resume(self.timer)
// addBall()方法里面
let littleBall:LittleBall = LittleBall(frame: CGRectMake(self.view.center.x, CGFloat(arc4random_uniform(UInt32(100))) * -1, 20, 20))
littleBall.backgroundColor = self.randomColor();
littleBall.layer.cornerRadius = 10
self.view.addSubview(littleBall)
viewArr += [littleBall]
gravity = nil
gravity = UIGravityBehavior(items: viewArr)
gravity.magnitude = 10
collision = nil
collision = UICollisionBehavior(items: viewArr)
collision.collisionDelegate = self
collision.addBoundaryWithIdentifier("path", fromPoint: CGPointMake(0, self.view.frame.height), toPoint: CGPointMake(self.view.frame.width, self.view.frame.height))
itemBehavior = nil
itemBehavior = UIDynamicItemBehavior(items: viewArr)
itemBehavior.elasticity = 0.5
self.animator.removeAllBehaviors()
self.animator.addBehavior(gravity)
self.animator.addBehavior(itemBehavior)
self.animator.addBehavior(collision)
//在代理方法里面
let view:UIView = item as! UIView
if view.frame.origin.x < 0 || view.frame.origin.x > self.view.frame.width{
let arr:NSMutableArray = NSMutableArray(array: self.viewArr)
view.removeFromSuperview()
arr.removeObject(view)
self.viewArr = arr as [AnyObject]
}
标签:
原文地址:http://www.cnblogs.com/superYou/p/4663403.html