跟着斯坦福白胡子老头学UIDynamic动画的技巧

UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架可以认为是一种物理引擎,能模拟和仿真现实生活中的物理重力、弹性碰撞、附着行为、捕捉行为、推动行为和动力元素等现象。

DropIt.gif

首先要在stroyboard里添加一个UIView, 并设置constraint跟父View边界相同(点击Reset to Suggested Constraints), 即充满屏幕。
我从这个Demo里总结了一些实际编码中可以用到的技巧, 供大家参数。

技巧1: 如果需要实现extension, 可以新建一个Swift文件, 一个类/枚举/结构体的所有扩展都放在同一个文件里(例如在A文件里扩展UIView,在B文件也扩展UIView, 这个语法不好维护,对同一个数据结构的扩展要放在一起!); 扩展在整个程序内都有效;示例代码:
<pre>
extension UIView {
//根据坐标判断对应的UIView
func hitTest(p: CGPoint) -> UIView? {
return hitTest(p, with: nil)
}
}

extension UIBezierPath {
//静态函数, 画直线
class func lineFrom(from: CGPoint, to: CGPoint) -> UIBezierPath {
let path = UIBezierPath()
path.move(to: from)
path.addLine(to: to)
return path
}
}
</pre>

技巧2:得到随机数, 在Swift语言里使用arc4random()方法,实际编码中建议使用扩展语法实现。 示例代码是CGFloat, 还可以是Int、Double等等。
<pre>
extension CGFloat {

/**
 *  返回范围内的随机数
 * @param max, 最大值
*/
static func random(max: Int) -> CGFloat {
    return CGFloat(arc4random() % UInt32(max))
}

}
</pre>

技巧3: UIView是所有界面空间的基类, 能添加子UIView(这点跟Andriod的View不同); 注意父UIView可以添加子UIView, 但是需要使用子UIView的方法才能移除(这点跟Android的ViewGroup不同)。
<pre>
let drop = UIView(frame: frame) //创建一个UIView
addSubview(drop) //添加drop到当前UIView里
drop.removeFromSuperview() //drop从父UIView中移除, 考虑一下drop执行了哪些生命周期函数?
</pre>

技巧4: 使用闭包语法为变量赋初值, lazy关键字为懒加载,即运行时调用了animator变量后才会执行闭包代码。
<pre>
private lazy var animator: UIDynamicAnimator = {
let animator = UIDynamicAnimator(referenceView: self)
animator.delegate = self
return animator
}()
</pre>

技巧5: 监听属性变化didSet/WillSet事件(观察者模式)并添加对应逻辑。 还记得前面博文提到的两个类相互引用的问题么,使用weak关键字解开闭环;注意下面代码, 如果在闭包里使用了self, 那么外部类实例和闭包之间形成了相互引用的关系, 这时需要使用[unowned self]避免内存泄漏。
<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关键字的功能, 这时要使用逗号。 下面示例代码的意思是dropToAttachTo不是nil时才执行后面的语句dropToAttachTo.superview != nil , 如果条件都满足则进入代码块。
<pre>
if let dropToAttachTo = lastDrop, dropToAttachTo.superview != nil {
attachment = UIAttachmentBehavior(item: dropToAttachTo, attachedToAnchor: gesturePoint)
}
</pre>

技巧7:对应Optional参数类型,即值可能为nil。 在Java语法里要写一堆的判空,语句间使用&&连接; Swift3.0省略了判空操作,再也不用写蛋疼的判空语句了。
请问下面的语句会崩溃吗?<pre>
attachment = nil
attachment?.anchorPoint = gesturePoint //attatchment后面是问号,说明他是Optional类型
</pre>答: 不会!
翻译一下: 如果attachment等于nil则不调用.后面的参数, 如果attachment有值则调用后面的参数。扩展一下可以是这样: attachment?.param1?.param2?.param3?.someValue , 如果用Java写这条语句要被累死!!!

技巧8: 自定义UIView绘制若干个图形时,可以使用Dictionary数组。 注意setNeedsDisplay函数类似于Android的invalidate,相当于设置个逻辑判断参数为true,UIView会在下个绘制周期时调用drawRect函数; 自定义UIView定义一个数组, 在drawRect函数里遍历并绘制。
<pre>
var bezierPaths = String:UIBezierPath {
didSet {
setNeedsDisplay() //触发刷新
}
}
override func draw(_ rect: CGRect) {
for (_, path) in bezierPaths {
path.stroke() //画线
}
} </pre>

代码下载地址:
https://github.com/brycegao/DropIt#dropit

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 简单整理下在Oc编译环境下如何与html文件进行交互,本文介绍两种比较简单的交互方式 第一种方法 —— 拦截UIW...
    杭州七木科技阅读 642评论 0 1
  • 清流独戏水,林荫小径踏歌行,炎暑听蛙鸣。清风微拂面,略有闲情,无浅草没马之感,却亦静心。酷暑虽难耐,别有风情。听虫...
    楚地小生阅读 490评论 0 7
  • #燃烧之鬼# #追凌# cr殊之 供梗来源:桑果mulberry 原梗作者:燃烧之鬼 蓝思追夜猎的时候,不慎沾上了...
    _殊之_阅读 2,544评论 2 19
  • 自打电子通讯设备软件有了飞越性的发展,对于我这种年年月月分不清几时何日的人,真是莫大的惊喜。不论时间如何度过,...
    一思瑶一阅读 257评论 1 1