iOS 9: Day by Day 第九天 UIKit Dynamics

本文翻譯自Chris Grant《iOS9 Day-by-Day :: Day 9 :: UIKit Dynamics》(https://www.shinobicontrols.com/blog/ios9-day-by-day-day9-uikit-dynamics)揽惹。感謝Chris Grant的辛苦工作宁昭!

iOS 7開始引入了UIKit Dynamics惑申,用來幫助開發(fā)者給界面添加真實(shí)的物理效果刻伊。在這個(gè)文章中將會(huì)看到封拧,iOS 9進(jìn)一步引入了許多新的內(nèi)容。

非矩形碰撞邊緣

在iOS 9以前碰逸,UIKitDynamics框架只支持矩形邊緣碰撞饰抒。這樣會(huì)導(dǎo)致非矩形物體碰撞時(shí)產(chǎn)生奇怪的視覺效果。iOS 9支持三種類型的碰撞邊緣:矩形脑漫、橢圓和路徑髓抑。其中路徑可以是任意逆時(shí)針并且不會(huì)自相交的形狀。有一點(diǎn)需要注意的是优幸,路徑只支持凸多邊形吨拍,而不支持凹多邊形。

通過子類化UIView可以提供自定義的碰撞邊緣類型网杆。

class Ellipse: UIView {
    override var collisionBoundsType: UIDynamicItemCollisionBoundsType {
        return .Ellipse
    }
}

對于自定義碰撞邊緣路徑的視圖羹饰,也可以這樣處理。

UIFieldBehavior

iOS 9以前只支持重力場效應(yīng)跛璧。這時(shí)其實(shí)已經(jīng)存在UIFieldBehavior類严里,只是SDK中還沒有通過子類將這些API暴露給用戶。

UIKit Dynamics中包含一下幾種場效應(yīng):

  • 線性重力場(Linear Gravity)
  • 徑向重力場(Radial Gravity)
  • 噪聲(Noise)
  • 自定義(Custom)

這些行為都有一系列的屬性進(jìn)行配置追城,從而對UIDynamicsAnimator中的視圖造成影響。它們的使用方法都非常簡單燥撞。

構(gòu)建一個(gè)UIFieldBehavior和不規(guī)則碰撞邊緣的例子

讓我們在下面的例子里組合使用這兩個(gè)新特征座柱。首先我們需要一對視圖(一個(gè)橢圓和一個(gè)方塊),并且添加一些碰撞邏輯以及一個(gè)噪聲場(UIFieldBehavior)物舒。

為了使用UIKit Dynamics色洞,首先需要設(shè)置UIDynamicAnimator。我們在視圖控制器中設(shè)置一個(gè)變量來引用它冠胯。

// Set up a UIDynamicAnimator on the view.
animator = UIDynamicAnimator(referenceView: view)

設(shè)置需要執(zhí)行動(dòng)畫的視圖:

// Add two views to the view
let square = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
square.backgroundColor = .blueColor()
view.addSubview(square)

let ellipse = Ellipse(frame: CGRect(x: 0, y: 100, width: 100, height: 100))
ellipse.backgroundColor = .yellowColor()
ellipse.layer.cornerRadius = 50
view.addSubview(ellipse)

給視圖添加重力行為:

let items = [square, ellipse]

// Create some gravity so the items always fall towards the bottom.
let gravity = UIGravityBehavior(items: items)
animator.addBehavior(gravity)

添加噪音:

let noiseField:UIFieldBehavior = UIFieldBehavior.noiseFieldWithSmoothness(1.0, animationSpeed: 0.5)
// Set up the noise field
noiseField.addItem(square)
noiseField.addItem(ellipse)
noiseField.strength = 0.5
animator.addBehavior(noiseField)

使用noiseFieldWithSmoothness創(chuàng)建一個(gè)噪音場火诸,并且將矩形和橢圓添加到這個(gè)行為中。

// Don't let objects overlap each other - set up a collide behaviour
let collision = UICollisionBehavior(items: items)
collision.setTranslatesReferenceBoundsIntoBoundaryWithInsets(UIEdgeInsets(top: 20, left: 5, bottom: 5, right: 5))
animator.addBehavior(collision)

UICollisionBehaviorsetTranslatesReferenceBoundsIntoBoundaryWithInsets方法可以創(chuàng)建一個(gè)矩形盒子荠察,允許視圖與邊緣發(fā)生碰撞置蜀。如果不使用這個(gè)碰撞盒,這兩個(gè)視圖可能會(huì)從下面掉出可視區(qū)域悉盆。

提到重力盯荤,如果它每次都指向設(shè)備的底部,用戶體驗(yàn)更好焕盟。換句話說秋秤,就是我們應(yīng)該使用現(xiàn)實(shí)世界中重力的方向。我們使用CoreMotion框架來獲取重力方向。

let manager:CMMotionManager = CMMotionManager()

為了持續(xù)的獲取方向的變化灼卢,我們需要一個(gè)引用該管理器的屬性绍哎。一旦開始獲取設(shè)備的動(dòng)作更新,我們就可以根據(jù)設(shè)備管理器的gravity屬性更新重力行為的gravityDirection鞋真。

// Used to alter the gravity so it always points down.
if manager.deviceMotionAvailable {
    manager.deviceMotionUpdateInterval = 0.1
    manager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler:{
        deviceManager, error in
        gravity.gravityDirection = CGVector(dx: deviceManager!.gravity.x, dy: -deviceManager!.gravity.y)
    })
}

注意蛇摸,這里只支持垂直方向的變化,如果需要支持所有的方向灿巧,應(yīng)該進(jìn)行額外的計(jì)算赶袄。

剛才的小矩形會(huì)在屏幕上到處移動(dòng),但是看不出來到底在發(fā)生什么事情抠藕。在WWDC session 229中饿肺,蘋果提供了一種可視化的動(dòng)畫調(diào)試方法。我們只需要給項(xiàng)目添加一個(gè)頭文件盾似,并加入一下代碼:

@import UIKit;

#if DEBUG

@interface UIDynamicAnimator (AAPLDebugInterfaceOnly)

/// Use this property for debug purposes when testing.
@property (nonatomic, getter=isDebugEnabled) BOOL debugEnabled;

@end

#endif

這樣會(huì)暴露UIDynamicAnimator的一些啟用調(diào)試模式的私有API敬辣。一旦啟用了調(diào)試模式,我們就可以看到視圖的受力情況零院「仍荆回到ViewController類,啟用調(diào)試模式告抄。

animator.debugEnabled = true // Private API. See the bridging header.

這樣撰茎,一旦我們啟動(dòng)應(yīng)用程序,就可以看到UIFiledBehavior的作用打洼。

我們同樣可以看到視圖的碰撞邊框以及矩形和方塊的碰撞邊緣龄糊。在lldb還有一些其它的調(diào)試屬性,比如debugIntervaldebugAnimationSpeed募疮。它們?yōu)檎{(diào)試UIKit Dynamics提供幫助炫惩。

我們可以看到場效應(yīng)對視圖的力的作用“⑴ǎ可以通過設(shè)置場效應(yīng)的對象的屬性來改變視圖的行為他嚷。我們通過添加一些控件來調(diào)節(jié)這些屬性。打開Interface Builder并添加三個(gè)UISlider控件芭毙。第一個(gè)控制場效應(yīng)的強(qiáng)度裳仆,第二個(gè)控制平滑度袋倔,最后一個(gè)控制速度硅堆。其中強(qiáng)度的變化方位是0-25皂冰,其它兩個(gè)是0-1。

一旦在Interface Buider中設(shè)置好這些控件苛聘,就可以通過拖拽連接控件與ViewController類涂炎。

@IBAction func smoothnessValueChanged(sender: UISlider) {
    noiseField.smoothness = CGFloat(sender.value)
}

@IBAction func speedValueChanged(sender: UISlider) {
    noiseField.animationSpeed = CGFloat(sender.value)
}

@IBAction func strengthValueChanged(sender: UISlider) {
    noiseField.strength = CGFloat(sender.value)
}

這樣忠聚,程序運(yùn)行后就可以通過控制三個(gè)屬性來觀察不同組合所產(chǎn)生的影響。

希望本文能夠給大家對UIFieldBehavior以及非矩形碰撞邊框的API的使用和調(diào)試提供一個(gè)大體的印象唱捣。建議大家在真機(jī)上運(yùn)行這個(gè)程序两蟀,這樣就可以充分利用動(dòng)作傳感器的效果。

更多信息

關(guān)于UIKit Dynamics新特性的更多信息震缭,可以看一下WWDC session 229(What's New in UIKit Dynamics and Visual Effects)的前半部分赂毯。別忘了在GitHub上還可以下到示例代碼。

戴維營教育

戴維營教育(Dive In Education)拣宰,潛心做IT職業(yè)教育党涕!緊跟時(shí)代潮流,不弄虛作假巡社!不忘初心膛堤!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市晌该,隨后出現(xiàn)的幾起案子肥荔,更是在濱河造成了極大的恐慌,老刑警劉巖朝群,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燕耿,死亡現(xiàn)場離奇詭異,居然都是意外死亡姜胖,警方通過查閱死者的電腦和手機(jī)誉帅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谭期,“玉大人堵第,你說我怎么就攤上這事∷沓觯” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵阀捅,是天一觀的道長胀瞪。 經(jīng)常有香客問我,道長饲鄙,這世上最難降的妖魔是什么凄诞? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮忍级,結(jié)果婚禮上帆谍,老公的妹妹穿的比我還像新娘。我一直安慰自己轴咱,他們只是感情好汛蝙,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布烈涮。 她就那樣靜靜地躺著,像睡著了一般窖剑。 火紅的嫁衣襯著肌膚如雪坚洽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天西土,我揣著相機(jī)與錄音讶舰,去河邊找鬼。 笑死需了,一個(gè)胖子當(dāng)著我的面吹牛跳昼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肋乍,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼鹅颊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了住拭?” 一聲冷哼從身側(cè)響起挪略,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滔岳,沒想到半個(gè)月后杠娱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谱煤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年摊求,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刘离。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡室叉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出硫惕,到底是詐尸還是另有隱情茧痕,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布恼除,位于F島的核電站踪旷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏豁辉。R本人自食惡果不足惜令野,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望徽级。 院中可真熱鬧气破,春花似錦、人聲如沸餐抢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至朴下,卻和暖如春努咐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背殴胧。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工渗稍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人团滥。 一個(gè)月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓竿屹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灸姊。 傳聞我的和親對象是個(gè)殘疾皇子拱燃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

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