- UIGravityBehavior为视图提供重力行为
UICollisionBehavior给视图增加碰撞边界
UIPushBehavior拖动view使用动画
UIGravityBehavior的使用,如果运行就开始动画,则使用代码1,如果指定事件运行,这是用代码2
这里是代码实现
class ViewController: UIViewController{ //给UI组件添加重力效果 // UIGravityBehavior var redView:UIView? var animator:UIDynamicAnimator? override func viewDidLoad() { super.viewDidLoad() redView = UIView.init(frame: CGRect.init(x: 100, y: 64, width: 100, height: 100)) if let theReadView = redView{ theReadView.backgroundColor = UIColor.red view.addSubview(theReadView) animator = UIDynamicAnimator.init(referenceView: view) //这里是代码1 /* if let theAnimator = animator{ let gravity = UIGravityBehavior.init(items: [theReadView]) theAnimator.addBehavior(gravity) } */ } } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { //这里是代码2 if let theReadView = redView{ let gravity = UIGravityBehavior.init(items: [theReadView]) animator?.addBehavior(gravity) } } }
这里可以看出来,RedView直接超出屏幕了,如果指定碰撞边界,或者防止两个碰撞重叠
UICollisionBehavior的使用
class ViewController: UIViewController{ //给UI组件添加重力效果 // UIGravityBehavior var squareViews = [AnyObject]() var animator:UIDynamicAnimator? override func viewDidLoad() { super.viewDidLoad() let colors = [UIColor.red,UIColor.blue] var currentCenterPoint = view.center let eachSize = CGSize.init(width: 50, height: 50) for counter in 0..<2{ let newView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: eachSize.width, height: eachSize.height)) newView.backgroundColor = colors[counter] newView.center = currentCenterPoint currentCenterPoint.y += eachSize.height+10 squareViews.append(newView) view.addSubview(newView) } } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { animator = UIDynamicAnimator.init(referenceView: self.view) /*创建重力*/ let gravity = UIGravityBehavior.init(items: squareViews as! [UIDynamicItem]) animator!.addBehavior(gravity) /*创建碰撞监测*/ let collision = UICollisionBehavior.init(items: squareViews as! [UIDynamicItem]) collision.translatesReferenceBoundsIntoBoundary = true//确保动画对象使用父视图作为参考视图进行初始化 animator!.addBehavior(collision) } }
以上都是垂直下落,但是如果自己设置下落路线,可以使用UICollisionBehavior的方法
open func addBoundary(withIdentifier identifier: NSCopying, from p1: CGPoint, to p2: CGPoint)
//withIdentifier 边界标识符,如果传入改表示符,就可以得到该对象 from开始点 to结束点 collision.addBoundary(withIdentifier: "Identifier" as NSCopying, from: CGPoint.init(x: 0, y: 0), to: CGPoint.init(x: view.bounds.size.width-50, y: view.bounds.size.height-50))
效果图
UICollisionBehaviorDelegate的使用,如果想要监测不同物体间的碰撞,可以使用代理,
当一个物体碰撞另外一个物体会实现代理方法,
public func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint)
当一个无物体脱离边界,不在于边界接触是,触发
public func collisionBehavior(_ behavior: UICollisionBehavior, endedContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?)
class ViewController: UIViewController,UICollisionBehaviorDelegate{ //给UI组件添加重力效果 // UIGravityBehavior var squareViews = [AnyObject]() var animator:UIDynamicAnimator? let bottomBoundary = "bottomBoundary" override func viewDidLoad() { super.viewDidLoad() let colors = [UIColor.red,UIColor.green] var currentCenterPoint = CGPoint.init(x: view.center.x, y: 0) let eachSize = CGSize.init(width: 50, height: 50) for counter in 0..<2{ let newView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: eachSize.width, height: eachSize.height)) newView.backgroundColor = colors[counter] newView.center = currentCenterPoint currentCenterPoint.y += eachSize.height+10 squareViews.append(newView) view.addSubview(newView) } } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { animator = UIDynamicAnimator.init(referenceView: self.view) /*创建重力*/ let gravity = UIGravityBehavior.init(items: squareViews as! [UIDynamicItem]) animator!.addBehavior(gravity) /*创建碰撞监测*/ let collision = UICollisionBehavior.init(items: squareViews as! [UIDynamicItem]) collision.translatesReferenceBoundsIntoBoundary = true//确保动画对象使用父视图作为参考视图进行初始化 //withIdentifier 边界标识符,如果传入改表示符,就可以得到该对象 from开始点 to结束点 collision.addBoundary(withIdentifier: bottomBoundary as NSCopying, from: CGPoint.init(x: 0, y: view.bounds.size.height-100), to: CGPoint.init(x: view.bounds.size.width, y: view.bounds.size.height-100)) collision.collisionDelegate = self animator!.addBehavior(collision) } // public func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint){ if identifier == nil{ return; } if identifier as? String == bottomBoundary{ UIView.animate(withDuration: 1, animations: { let view = item as! UIView view.backgroundColor = UIColor.red view.alpha = 0 view.transform = CGAffineTransform.init(scaleX: 2, y: 2) }) { (finish) in let view = item as! UIView behavior.removeItem(item) view.removeFromSuperview() } } } }
UIPushBehavior的使用
class ViewController: UIViewController{ // UIPushBehavior 推动,需要设置推动的弧度和推动的力量值,就是angle和magnitude var squareView :UIView? var animator :UIDynamicAnimator? var pushBehavior :UIPushBehavior? //初始化squareView func createSmallSquareView(){ squareView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 80, height: 80)) if let theSquareView = squareView{ theSquareView.backgroundColor = UIColor.green theSquareView.center = view.center view.addSubview(theSquareView) } } func createGestureRecognizer(){ let gapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(hadleTop(tap:))); self.view.addGestureRecognizer(gapGestureRecognizer) } func createAnimatorAndBehaviors(){ animator = UIDynamicAnimator.init(referenceView: self.view) if let theSquareView = squareView{ /*创建碰撞监测*/ let collision = UICollisionBehavior.init(items: [squareView] as! [UIDynamicItem]) collision.translatesReferenceBoundsIntoBoundary = true//确保动画对象使用父视图作为参考视图进行初始化 pushBehavior = UIPushBehavior.init(items: [theSquareView], mode: .continuous) animator?.addBehavior(collision) animator?.addBehavior(pushBehavior!) } } override func viewDidLoad() { super.viewDidLoad() createGestureRecognizer() createSmallSquareView() createAnimatorAndBehaviors() } @objc func hadleTop(tap:UITapGestureRecognizer){ let tapPoint = tap.location(in: view) let squareViewCenterPoint = self.squareView!.center /*获取方块与中心点的距离*/ let deltax = tapPoint.x - squareViewCenterPoint.x let dettay = tapPoint.y - squareViewCenterPoint.y /*计算方块视图和点击触点的角度,从而得到推动的角度,用户监测两个点角度的公式*/ let angle = atan2(dettay, deltax) pushBehavior!.angle = angle //设置推动的弧度 /*距离公式*/ let distanceBetweenPoints = sqrt(pow(tapPoint.x - squareViewCenterPoint.x, 2.0)+pow(tapPoint.y-squareViewCenterPoint.y, 2.0)) pushBehavior!.magnitude = distanceBetweenPoints/200.0//设置重力值,越大,相当于对于的力量越大,每一个点力量值会实现100点每平方秒的加速度 } }