zoukankan      html  css  js  c++  java
  • Swift中创建有动态交互性的用户界面UIDynamics的使用(一)

    • UIGravityBehavior为视图提供重力行为
    • UICollisionBehavior给视图增加碰撞边界

    • UIPushBehavior拖动view使用动画

    • UISnapBehavior拖动到指定位置

    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,  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( 50, height: 50)
            for counter in 0..<2{
                let newView = UIView.init(frame: CGRect.init(x: 0, y: 0,  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( 50, height: 50)
            for counter in 0..<2{
                let newView = UIView.init(frame: CGRect.init(x: 0, y: 0,  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,  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点每平方秒的加速度
            
        }
        
        
    }
    

    UISnapBehavior的使用

    class ViewController: UIViewController{
        
        // UIPushBehavior 推动,需要设置推动的弧度和推动的力量值,就是angle和magnitude
        var squareView :UIView?
        var animator :UIDynamicAnimator?
        var snapBehavior :UISnapBehavior?
        
        //初始化squareView
        func createSmallSquareView(){
            squareView = UIView.init(frame: CGRect.init(x: 0, y: 0,  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//确保动画对象使用父视图作为参考视图进行初始化
                snapBehavior = UISnapBehavior.init(item: theSquareView, snapTo: theSquareView.center)
                snapBehavior!.damping = 0.5
                animator?.addBehavior(collision)
                animator?.addBehavior(snapBehavior!)
            }
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            createGestureRecognizer()
            createSmallSquareView()
            createAnimatorAndBehaviors()
            
        }
        @objc func hadleTop(tap:UITapGestureRecognizer){
            let tapPoint = tap.location(in: view)
            if let theSnap = snapBehavior{
                animator!.removeBehavior(theSnap)
            }
            
            snapBehavior = UISnapBehavior.init(item: squareView!, snapTo: tapPoint)
            snapBehavior!.damping = 0.5
            animator?.addBehavior(snapBehavior!)
            
        }
        
        
    }
    
  • 相关阅读:
    编程实践56
    诫子篇
    编程实践58
    编程实践55
    C#Process类应该声明个什么引用空间啊 找不到类型或命名空间名称“Process”(是否缺少 using 指令或程序集引用?) 如何解决?
    课堂题目54
    jQuery学习笔记jQuery的动画
    Asp.net生成各种网页快捷方式[转贴]
    jQuery学习笔记Helloworld
    FreeTextBox配置
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/12020669.html
Copyright © 2011-2022 走看看