iOS重力行爲、碰撞行爲和吸附(Swift)

iOS有模仿物理環境的動態動畫,今天就簡單的給視圖添加重力效果和碰撞效果

首先使用一個參考視圖也可以理解爲背景視圖創建自動動畫:

dynamicAnimator = UIDynamicAnimator(referenceView: self.view)

並且我們創建兩個一大一小的視圖:

        litterView = createGlobe(CGRectMake(145, 20, 50, 50), color: UIColor.yellowColor())
        hugeView = createGlobe(CGRectMake(120, 300, 100, 100), color: UIColor.redColor())
        self.view.addSubview(litterView!)
        self.view.addSubview(hugeView!)


 func createGlobe(frame:CGRect,color:UIColor) -> UIView{
        let view = UIView (frame: frame)
        view.backgroundColor = color
        view.layer.borderColor = UIColor.greenColor().CGColor
        view.layer.cornerRadius = frame.size.width/2
        view.layer.masksToBounds = true
        view.layer.borderWidth = 2
        return view
    }

然後我們給小的視圖添加重力行爲並設置加速度:

        //重力行爲
        let gravite = UIGravityBehavior(items: [litterView!])
        //加速度
        gravite.magnitude = 5

給大視圖和小視圖都添加碰撞行爲

        //碰撞行爲
        let collisionBehavior = UICollisionBehavior(items: [litterView!,hugeView!])
        //用參考視圖邊界作爲碰撞邊界
        collisionBehavior.translatesReferenceBoundsIntoBoundary = true
        collisionBehavior.collisionDelegate = self

碰撞行爲是有代理方法的,我們可以通過實現代理方法監聽碰撞過程:
兩個視圖碰撞結束:

 func collisionBehavior(behavior: UICollisionBehavior, endedContactForItem item1: UIDynamicItem, withItem item2: UIDynamicItem) {
        let color = hugeView!.backgroundColor
        hugeView!.backgroundColor = litterView!.backgroundColor
        litterView!.backgroundColor = color
    }

視圖開始與邊界碰撞:

 func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, atPoint p: CGPoint) {

    }

視圖結束與邊界碰撞:

 func collisionBehavior(behavior: UICollisionBehavior, endedContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?) {

    }

爲了使效果看起來更加真實我們可以給視圖添加一些物理屬性:
給小視圖添加彈性和密度值:

        //物體屬性行爲包括彈性、摩擦力、密度、阻力等等
        let litterBehavior = UIDynamicItemBehavior(items: [litterView!])
        litterBehavior.elasticity = 0.6
        //密度
        litterBehavior.density = 2.2

給大視圖添加彈性、阻力和密度值:

       let hugeBehavior = UIDynamicItemBehavior(items: [hugeView!])
        //彈性
        hugeBehavior.elasticity = 0.8
        //阻力
        hugeBehavior.resistance = 0.3
        hugeBehavior.density = 12.2

接下來我們再創建一箇中型的視圖併爲它添加吸附行爲:

 middleView = createGlobe(CGRectMake(200, 100, 75, 75), color: UIColor.whiteColor())
 self.view.addSubview(middleView!)

創建吸附行爲時要有視圖和點這兩個參數:

 snapBheavior = UISnapBehavior(item: middleView!, snapToPoint: point!)

我們還可以給吸附添加物理屬性:

 //阻尼
 snapBheavior?.damping = 0.2

下面是完整的demo代碼:

//
//  ViewController.swift
//  重力碰撞
//
//  Created by 句芒 on 16/8/16.
//  Copyright © 2016年 fanwei. All rights reserved.
//

import UIKit

class ViewController: UIViewController,UICollisionBehaviorDelegate{

    var dynamicAnimator = UIDynamicAnimator()
    var snapBheavior:UISnapBehavior?
    var litterView:UIView?
    var hugeView:UIView?
    var middleView:UIView?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor.blackColor()

        dynamicAnimator = UIDynamicAnimator(referenceView: self.view)

        litterView = createGlobe(CGRectMake(145, 20, 50, 50), color: UIColor.yellowColor())
        middleView = createGlobe(CGRectMake(200, 100, 75, 75), color: UIColor.whiteColor())
        hugeView = createGlobe(CGRectMake(120, 300, 100, 100), color: UIColor.redColor())

        self.view.addSubview(litterView!)
        self.view.addSubview(hugeView!)
        self.view.addSubview(middleView!)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //重力行爲
        let gravite = UIGravityBehavior(items: [litterView!])
        //加速度
        gravite.magnitude = 5

        //碰撞行爲
        let collisionBehavior = UICollisionBehavior(items: [litterView!,hugeView!,middleView!])
        //用參考視圖邊界作爲碰撞邊界
        collisionBehavior.translatesReferenceBoundsIntoBoundary = true
        collisionBehavior.collisionDelegate = self

        //物體屬性行爲包括彈性、摩擦力、密度、阻力等等
        let litterBehavior = UIDynamicItemBehavior(items: [litterView!])
        litterBehavior.elasticity = 0.6
        //密度
        litterBehavior.density = 2.2


        let hugeBehavior = UIDynamicItemBehavior(items: [hugeView!])
        //彈性
        hugeBehavior.elasticity = 0.8
        //阻力
        hugeBehavior.resistance = 0.3
        hugeBehavior.density = 12.2

        dynamicAnimator.addBehavior(gravite)
        dynamicAnimator.addBehavior(collisionBehavior)
        dynamicAnimator.addBehavior(litterBehavior)
        dynamicAnimator.addBehavior(hugeBehavior)
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
         let touch = touches.first
         let point = touch?.locationInView(self.view)
        //刪除原有的吸附
        if snapBheavior != nil {
            dynamicAnimator.removeBehavior(snapBheavior!)
        }
        //添加新吸附
        snapBheavior = UISnapBehavior(item: middleView!, snapToPoint: point!)
        //阻尼
        snapBheavior?.damping = 0.2
        dynamicAnimator.addBehavior(snapBheavior!)

    }

    func createGlobe(frame:CGRect,color:UIColor) -> UIView{
        let view = UIView (frame: frame)
        view.backgroundColor = color
        view.layer.borderColor = UIColor.greenColor().CGColor
        view.layer.cornerRadius = frame.size.width/2
        view.layer.masksToBounds = true
        view.layer.borderWidth = 2
        return view
    }

    func collisionBehavior(behavior: UICollisionBehavior, endedContactForItem item1: UIDynamicItem, withItem item2: UIDynamicItem) {
        let color = hugeView!.backgroundColor
        hugeView!.backgroundColor = litterView!.backgroundColor
        litterView!.backgroundColor = color
    }

    func collisionBehavior(behavior: UICollisionBehavior, endedContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?) {

    }

    func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, atPoint p: CGPoint) {

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章