Swift中创建有动态交互性的用户界面UIDynamics的使用(一)

时间:2019-12-12
本文章向大家介绍Swift中创建有动态交互性的用户界面UIDynamics的使用(一),主要包括Swift中创建有动态交互性的用户界面UIDynamics的使用(一)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
  • 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点每平方秒的加速度
        
    }
    
    
}

原文地址:https://www.cnblogs.com/hualuoshuijia/p/12020669.html