跟著斯坦福白胡子老頭學(xué)UIDynamic動畫的技巧

UIDynamic是從iOS 7開始引入的一種新技術(shù)吸申,隸屬于UIKit框架可以認(rèn)為是一種物理引擎两嘴,能模擬和仿真現(xiàn)實(shí)生活中的物理重力、彈性碰撞届慈、附著行為徒溪、捕捉行為、推動行為和動力元素等現(xiàn)象金顿。

DropIt.gif

首先要在stroyboard里添加一個UIView臊泌, 并設(shè)置constraint跟父View邊界相同(點(diǎn)擊Reset to Suggested Constraints), 即充滿屏幕揍拆。
我從這個Demo里總結(jié)了一些實(shí)際編碼中可以用到的技巧渠概, 供大家參數(shù)。

技巧1: 如果需要實(shí)現(xiàn)extension礁凡, 可以新建一個Swift文件高氮, 一個類/枚舉/結(jié)構(gòu)體的所有擴(kuò)展都放在同一個文件里(例如在A文件里擴(kuò)展UIView慧妄,在B文件也擴(kuò)展UIView顷牌, 這個語法不好維護(hù),對同一個數(shù)據(jù)結(jié)構(gòu)的擴(kuò)展要放在一起H汀)窟蓝; 擴(kuò)展在整個程序內(nèi)都有效;示例代碼:
<pre>
extension UIView {
//根據(jù)坐標(biāo)判斷對應(yīng)的UIView
func hitTest(p: CGPoint) -> UIView? {
return hitTest(p, with: nil)
}
}

extension UIBezierPath {
//靜態(tài)函數(shù), 畫直線
class func lineFrom(from: CGPoint, to: CGPoint) -> UIBezierPath {
let path = UIBezierPath()
path.move(to: from)
path.addLine(to: to)
return path
}
}
</pre>

技巧2:得到隨機(jī)數(shù), 在Swift語言里使用arc4random()方法运挫,實(shí)際編碼中建議使用擴(kuò)展語法實(shí)現(xiàn)状共。 示例代碼是CGFloat, 還可以是Int谁帕、Double等等峡继。
<pre>
extension CGFloat {

/**
 *  返回范圍內(nèi)的隨機(jī)數(shù)
 * @param max, 最大值
*/
static func random(max: Int) -> CGFloat {
    return CGFloat(arc4random() % UInt32(max))
}

}
</pre>

技巧3: UIView是所有界面空間的基類, 能添加子UIView(這點(diǎn)跟Andriod的View不同)匈挖; 注意父UIView可以添加子UIView碾牌, 但是需要使用子UIView的方法才能移除(這點(diǎn)跟Android的ViewGroup不同)。
<pre>
let drop = UIView(frame: frame) //創(chuàng)建一個UIView
addSubview(drop) //添加drop到當(dāng)前UIView里
drop.removeFromSuperview() //drop從父UIView中移除儡循, 考慮一下drop執(zhí)行了哪些生命周期函數(shù)舶吗?
</pre>

技巧4: 使用閉包語法為變量賦初值, lazy關(guān)鍵字為懶加載择膝,即運(yùn)行時調(diào)用了animator變量后才會執(zhí)行閉包代碼誓琼。
<pre>
private lazy var animator: UIDynamicAnimator = {
let animator = UIDynamicAnimator(referenceView: self)
animator.delegate = self
return animator
}()
</pre>

技巧5: 監(jiān)聽屬性變化didSet/WillSet事件(觀察者模式)并添加對應(yīng)邏輯。 還記得前面博文提到的兩個類相互引用的問題么肴捉,使用weak關(guān)鍵字解開閉環(huán)腹侣;注意下面代碼, 如果在閉包里使用了self每庆, 那么外部類實(shí)例和閉包之間形成了相互引用的關(guān)系筐带, 這時需要使用[unowned self]避免內(nèi)存泄漏。
<pre>
private var attachment: UIAttachmentBehavior? {
willSet {
if attachment != nil {
... //attachment值變化前缤灵,做邏輯
}
}
didSet {
if attachment != nil {
... //attachment值變化后伦籍,做邏輯
attachment!.action = {[unowned self] in
if let attachedrop = self.attachment!.items.first as? UIView {
self.bezierPaths["line"] = UIBezierPath.lineFrom(from: (self.attachment?.anchorPoint)!, to: attachedrop.center)
}
}
}
}
}<</pre>

技巧6: if邏輯判斷需要where關(guān)鍵字的功能, 這時要使用逗號腮出。 下面示例代碼的意思是dropToAttachTo不是nil時才執(zhí)行后面的語句dropToAttachTo.superview != nil 帖鸦, 如果條件都滿足則進(jìn)入代碼塊。
<pre>
if let dropToAttachTo = lastDrop, dropToAttachTo.superview != nil {
attachment = UIAttachmentBehavior(item: dropToAttachTo, attachedToAnchor: gesturePoint)
}
</pre>

技巧7:對應(yīng)Optional參數(shù)類型胚嘲,即值可能為nil作儿。 在Java語法里要寫一堆的判空,語句間使用&&連接馋劈; Swift3.0省略了判空操作攻锰,再也不用寫蛋疼的判空語句了。
請問下面的語句會崩潰嗎妓雾?<pre>
attachment = nil
attachment?.anchorPoint = gesturePoint //attatchment后面是問號娶吞,說明他是Optional類型
</pre>答: 不會!
翻譯一下: 如果attachment等于nil則不調(diào)用.后面的參數(shù)械姻, 如果attachment有值則調(diào)用后面的參數(shù)妒蛇。擴(kuò)展一下可以是這樣: attachment?.param1?.param2?.param3?.someValue , 如果用Java寫這條語句要被累死!P宥帷吏奸!

技巧8: 自定義UIView繪制若干個圖形時,可以使用Dictionary數(shù)組陶耍。 注意setNeedsDisplay函數(shù)類似于Android的invalidate奋蔚,相當(dāng)于設(shè)置個邏輯判斷參數(shù)為true,UIView會在下個繪制周期時調(diào)用drawRect函數(shù)烈钞; 自定義UIView定義一個數(shù)組旺拉, 在drawRect函數(shù)里遍歷并繪制。
<pre>
var bezierPaths = String:UIBezierPath {
didSet {
setNeedsDisplay() //觸發(fā)刷新
}
}
override func draw(_ rect: CGRect) {
for (_, path) in bezierPaths {
path.stroke() //畫線
}
} </pre>

代碼下載地址:
https://github.com/brycegao/DropIt#dropit

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末棵磷,一起剝皮案震驚了整個濱河市蛾狗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仪媒,老刑警劉巖沉桌,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異算吩,居然都是意外死亡留凭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門偎巢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔼夜,“玉大人,你說我怎么就攤上這事压昼∏罄洌” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵窍霞,是天一觀的道長匠题。 經(jīng)常有香客問我,道長但金,這世上最難降的妖魔是什么韭山? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮冷溃,結(jié)果婚禮上钱磅,老公的妹妹穿的比我還像新娘。我一直安慰自己似枕,他們只是感情好盖淡,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菠净,像睡著了一般禁舷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毅往,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天牵咙,我揣著相機(jī)與錄音,去河邊找鬼攀唯。 笑死洁桌,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的侯嘀。 我是一名探鬼主播另凌,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戒幔!你這毒婦竟也來了吠谢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤诗茎,失蹤者是張志新(化名)和其女友劉穎工坊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敢订,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡王污,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了楚午。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昭齐。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖矾柜,靈堂內(nèi)的尸體忽然破棺而出阱驾,到底是詐尸還是另有隱情,我是刑警寧澤怪蔑,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布啊易,位于F島的核電站,受9級特大地震影響饮睬,放射性物質(zhì)發(fā)生泄漏租谈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一捆愁、第九天 我趴在偏房一處隱蔽的房頂上張望割去。 院中可真熱鬧,春花似錦昼丑、人聲如沸呻逆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咖城。三九已至茬腿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宜雀,已是汗流浹背治宣。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工眠蚂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糖儡,地道東北人白对。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像简烘,于是被迫代替她去往敵國和親苔严。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫孤澎、插件届氢、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評論 4 62
  • 簡單整理下在Oc編譯環(huán)境下如何與html文件進(jìn)行交互,本文介紹兩種比較簡單的交互方式 第一種方法 —— 攔截UIW...
    杭州七木科技閱讀 647評論 0 1
  • 清流獨(dú)戲水覆旭,林蔭小徑踏歌行悼沈,炎暑聽蛙鳴。清風(fēng)微拂面姐扮,略有閑情絮供,無淺草沒馬之感,卻亦靜心茶敏∪腊校酷暑雖難耐,別有風(fēng)情惊搏。聽蟲...
    楚地小生閱讀 493評論 0 7
  • #燃燒之鬼# #追凌# cr殊之 供梗來源:桑果mulberry 原梗作者:燃燒之鬼 藍(lán)思追夜獵的時候贮乳,不慎沾上了...
    _殊之_閱讀 2,549評論 2 19
  • 自打電子通訊設(shè)備軟件有了飛越性的發(fā)展,對于我這種年年月月分不清幾時何日的人恬惯,真是莫大的驚喜向拆。不論時間如何度過,...
    一思瑤一閱讀 259評論 1 1