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.
}
}