UIkit Dynamics

UIkit Dynamics是UIkit的一套基于現(xiàn)實(shí)世界物理驅(qū)動(dòng)的一套交互體系,包含了我們常見的物理知識現(xiàn)象晤锥,如重力掉蔬、碰撞、彈力等效果矾瘾。而UIKit Dynamice提供了一整套逼真的物理動(dòng)作女轿,在實(shí)現(xiàn)一些逼真的物理效果的時(shí)事倍功半。

有四個(gè)概念我們來稍微描述一下:

  • UIDynamicItem 就是物理體系可以影響到的物體壕翩,像現(xiàn)實(shí)世界的桌子蛉迹、椅子。在ios我們常見的UI控件像UIButton戈泼、UIView等實(shí)現(xiàn)了該接口婿禽。
  • UIDynamicBehavior 一個(gè)行為,像重力或者彈性大猛、吸附等效果
  • UIDynamicAnimator 一個(gè)動(dòng)畫執(zhí)行者扭倾,所有的行為都可以加入這個(gè)執(zhí)行者,重力+碰撞就可以模擬高空墜落拉挽绩!
  • referenceView 參照體系膛壹,就像現(xiàn)實(shí)世界的參照物。

一、重力行為UIGravityBehavior

var animator : UIDynamicAnimator!
override func viewDidLoad() {
    super.viewDidLoad()
    //box
    let box : UIView = UIView(frame: CGRectMake(135, 80, 50, 50))
    box.backgroundColor = UIColor.grayColor()
    self.view.backgroundColor = UIColor.whiteColor()
    self.view.addSubview(box)
    //參照物為背景view
    self.animator = UIDynamicAnimator(referenceView: self.view)
    //為box添加重力行為
    let gravity = UIGravityBehavior(items: [box])
    //執(zhí)行動(dòng)畫
    self.animator.addBehavior(gravity)
}

這里注意把a(bǔ)nimator聲明為類的成員變量模聋,不然animator在viewDidLoad后就釋放內(nèi)存引用肩民,就沒有什么重力效果了。

GIF效果圖

我們可以設(shè)置重力的向量链方,大小和方向就是墜落的方向和下墜加速度了持痰。

<code>gravity.gravityDirection = CGVector(dx: 0, dy: 5)</code>

二、碰撞行為UICollisionBehavior

就這么無休止的墜落深淵未免也太無聊了吧,我們來讓那個(gè)它跟屏幕下方進(jìn)行碰撞。

var animator : UIDynamicAnimator!
override func viewDidLoad() {
    super.viewDidLoad()
    //box
    let box : UIView = UIView(frame: CGRectMake(135, 80, 50, 50))
    box.backgroundColor = UIColor.grayColor()
    self.view.backgroundColor = UIColor.whiteColor()
    self.view.addSubview(box)
    //參照物為背景view
    self.animator = UIDynamicAnimator(referenceView: self.view)
    //為box添加重力行為
    let gravity = UIGravityBehavior(items: [box])
    //執(zhí)行動(dòng)畫
    self.animator.addBehavior(gravity)
GIF效果圖

三辞嗡、連線行為UIAttachmentBehavior

連線就是兩個(gè)物體之間進(jìn)行連接或者一個(gè)物體跟一個(gè)錨點(diǎn)之間連接。

參數(shù)說明:UIAttachmentBehavior(item: offsetFromCenter: attachedToAnchor: )

  • item:物理體系可以影響到的物體

  • offsetFromCenter:物體中心偏移

  • attachedToAnchor:跟物體相連的錨點(diǎn)

      var animator : UIDynamicAnimator!
      override func viewDidLoad() {
             super.viewDidLoad()
      
            animator = UIDynamicAnimator(referenceView: self.view)
      
            //靜止的box
            let staticBox = UIView(frame: CGRectMake(50, 50, 50, 50))
            staticBox.backgroundColor = UIColor.redColor()
            staticBox.layer.cornerRadius = 5 ;
           //下墜的box
           let dynamicBox = UIView(frame: CGRectMake(250, 50, 50, 50))
          dynamicBox.backgroundColor = UIColor.grayColor()
          dynamicBox.layer.cornerRadius = 5 ;
      
            //為dynamicBox添加重力行為
            let cravity = UIGravityBehavior(items: [dynamicBox])
          //為dynamicBox添加連線行為
           let attachment = UIAttachmentBehavior(item: dynamicBox, offsetFromCenter: UIOffsetMake(0, 0), attachedToAnchor: CGPointMake(staticBox.center.x, staticBox.center.y))
          //為dynamicBox添加碰撞行為
          let collision = UICollisionBehavior(items: [dynamicBox])
          collision.translatesReferenceBoundsIntoBoundary = true
      
          self.view.addSubview(staticBox)
          self.view.addSubview(dynamicBox)
      
          animator.addBehavior(cravity)
          animator.addBehavior(attachment)
          animator.addBehavior(collision) 
     }
    
GIF效果圖

想讓“繩子”有彈性加上這段:<code>attachment.frequency = 1</code>

四珊佣、吸附行為UISnapBehavior

很有趣的“牛皮糖”效果

var animator : UIDynamicAnimator!
let tapGesture = UITapGestureRecognizer()
var box:UIView!  
override func viewDidLoad() {
    super.viewDidLoad()
    
    //添加手勢,輕觸self.view,
    self.tapGesture.addTarget(self, action: "tappedView")
    self.view.userInteractionEnabled = true ;
    self.view.addGestureRecognizer(tapGesture)
    
    self.animator = UIDynamicAnimator(referenceView: self.view)
    
    // Do any additional setup after loading the view, typically from a nib.
    //物體
    self.box = UIView(frame: CGRectMake(110, 50, 100, 100))
    box.backgroundColor = UIColor.grayColor()
    box.layer.cornerRadius = 5
    
    self.view.addSubview(box)
}

//手勢回調(diào)方法
func tappedView(){
    let point = self.tapGesture.locationInView(self.view)
    self.animator.removeAllBehaviors()
    let snap = UISnapBehavior(item: self.box, snapToPoint: point)
    self.animator.addBehavior(snap)
}
GIF效果圖

四、推力UIPushBehavior

為物體施加一個(gè)外力淹仑,遵循力的合成

var box : UIView!
var animator : UIDynamicAnimator!
var push : UIPushBehavior!    
let tapGetsture = UITapGestureRecognizer()

override func viewDidLoad() {
    super.viewDidLoad()
    self.animator = UIDynamicAnimator(referenceView: self.view)
    
    //self.view加入輕觸手勢
    self.tapGetsture.addTarget(self, action: "tappedView")
    self.view.userInteractionEnabled = true
    self.view.addGestureRecognizer(tapGetsture)
    
    //box
    self.box = UIView(frame: CGRectMake(110, 234, 100, 100))
    self.box.layer.cornerRadius = 5 ;
    self.box.backgroundColor = UIColor.grayColor()

    //加入box
    self.view.addSubview(self.box)
    //碰撞
    let collision = UICollisionBehavior(items: [box])
     collision.setTranslatesReferenceBoundsIntoBoundaryWithInsets(UIEdgeInsets(top: self.topLayoutGuide.length, left: 0, bottom: self.bottomLayoutGuide.length, right: 0))
    //推力
    self.push = UIPushBehavior(items: [self.box], mode: UIPushBehaviorMode.Instantaneous)
    self.push.angle = 0
    self.push.magnitude = 0 ;
    
    //加入行為
    self.animator.addBehavior(self.push)
    self.animator.addBehavior(collision)
}

//輕觸手勢
func tappedView(){
    
    let tapPoint = self.tapGetsture.locationInView(self.view)
    let centerPoint = CGPointMake(self.box.center.x, self.box.center.y)
    
    //角度和大小
    let angle =  atan2(tapPoint.y - centerPoint.y, tapPoint.x - centerPoint.x)
    var distance = sqrtf(powf(Float(tapPoint.x - centerPoint.x),2.0) + powf(Float(tapPoint.y - centerPoint.y),2))
    distance =  min(distance, 100.00)
    
    self.push.setAngle(angle, magnitude: CGFloat(distance/100))
    
    //每次更改push屬性時(shí),push都會(huì)變?yōu)椴豢苫顒?dòng)狀態(tài)肺孵,需要手動(dòng)更改active為true
    self.push.active = true ;
    }
GIF效果圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匀借,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子悬槽,更是在濱河造成了極大的恐慌怀吻,老刑警劉巖瞬浓,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件初婆,死亡現(xiàn)場離奇詭異,居然都是意外死亡猿棉,警方通過查閱死者的電腦和手機(jī)磅叛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萨赁,“玉大人弊琴,你說我怎么就攤上這事≌人” “怎么了敲董?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長慰安。 經(jīng)常有香客問我腋寨,道長,這世上最難降的妖魔是什么化焕? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任萄窜,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘查刻。我一直安慰自己键兜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布穗泵。 她就那樣靜靜地躺著普气,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佃延。 梳的紋絲不亂的頭發(fā)上棋电,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音苇侵,去河邊找鬼赶盔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛榆浓,可吹牛的內(nèi)容都是我干的于未。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼陡鹃,長吁一口氣:“原來是場噩夢啊……” “哼烘浦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起萍鲸,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤闷叉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后脊阴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體握侧,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年嘿期,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了品擎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡备徐,死狀恐怖萄传,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜜猾,我是刑警寧澤秀菱,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站蹭睡,受9級特大地震影響衍菱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棠笑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一梦碗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦洪规、人聲如沸印屁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雄人。三九已至,卻和暖如春念赶,著一層夾襖步出監(jiān)牢的瞬間础钠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工叉谜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旗吁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓停局,卻偏偏與公主長得像很钓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子董栽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容