iOS開(kāi)發(fā)之UIKit Dynamics學(xué)習(xí)心得

在iOS7上新增加了UIKit Dynamic讨韭,它能夠讓UIView模擬逼真的物理效果脂信。如重力,碰撞透硝,彈簧狰闪,吸附等效果,有了這些效果能輕松的提高應(yīng)用的用戶體驗(yàn)濒生。想要實(shí)現(xiàn)這些力學(xué)動(dòng)畫(huà)效果埋泵,首先要?jiǎng)?chuàng)建一個(gè)力學(xué)動(dòng)畫(huà)生成器(UIDynamicAnimator),然后使用各種行為進(jìn)行定制罪治,可用于定制UIDynamicAnimator的行為的類有:UIAttachmentBehavior丽声,UICollisionBehaviorUIGravityBehavior觉义,UIDynamicItemBehavior恒序,UIPushBehaviorUISnapBehavior谁撼。他們能夠賦予UIView逼真的行為和動(dòng)畫(huà)歧胁。

NOTE:每個(gè)力學(xué)動(dòng)畫(huà)生成器都是獨(dú)立的滋饲,多個(gè)動(dòng)畫(huà)力學(xué)生成器可同時(shí)運(yùn)行。要讓力學(xué)動(dòng)畫(huà)生成器持續(xù)運(yùn)行喊巍,必須要有指向它的有效應(yīng)用屠缭。一旦動(dòng)畫(huà)處于靜止?fàn)顟B(tài)(如彈簧效果恢復(fù)原狀)之后,力學(xué)動(dòng)畫(huà)生成器將暫停崭参,不在執(zhí)行任何計(jì)算了呵曹。但是對(duì)于未用的力學(xué)動(dòng)畫(huà)生成器,最好把它刪除掉何暮。

生成一個(gè)力學(xué)動(dòng)畫(huà)生成器

UIDynamicAnimator *animator =[ [UIDynamicAnimator alloc] initWithReferenceView:self.view];//行為視圖的父視圖必須是動(dòng)畫(huà)生成器的參考視圖
[animator addBehavior:aDynamicBeahvior];//aDynamicBeahvior是一個(gè)行為

重力(UIGravityBehavior)

重力的效果如圖所示:

對(duì)于重力行為奄喂,需要注意的有角度(angle)和量級(jí)(magnitude,我也叫它重力加速度)海洼,實(shí)現(xiàn)代碼如下:

UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[footballView]];
 //angle:角度(弧度)  magnitude:量級(jí)(重力系數(shù))
[gravityBehavior setAngle:3.14/2 magnitude:0.1f];
[self.animator addBehavior:gravityBehavior];

碰撞(UICollisionBehavior)

說(shuō)到碰撞跨新,一個(gè)是物體之間的碰撞,一個(gè)是與邊界的碰撞坏逢,在上面的重力效果演示圖中域帐,足球從上落下,一直落到屏幕之外是整,這是由于我們沒(méi)有給他設(shè)置邊界肖揣。我們看看碰撞的效果圖:

我給圖中的籃球足球設(shè)置了重力效果和碰撞效果,代碼如下:

UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.footballView,self.basketballView]];
[gravityBehavior setAngle:3.14/2 magnitude:0.1f];   
//碰撞效果
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.footballView,self.basketballView]];
[collisionBehavior setCollisionMode:UICollisionBehaviorModeEverything];//碰撞效果浮入,必須指定的
/**
 *  UICollisionBehaviorModeEverything:物體既相互碰撞又與邊界碰撞
 *  UICollisionBehaviorModeBoundaries:物體不相互碰撞龙优,只與邊界碰撞
 *  UICollisionBehaviorModeItems:物體相互碰撞,不與邊界碰撞
 */
//設(shè)置邊界為動(dòng)畫(huà)器參考view的視圖范圍
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
//代理可以監(jiān)聽(tīng)碰撞
collisionBehavior.collisionDelegate = self;
[self.animator addBehavior:gravityBehavior];
[self.animator addBehavior:collisionBehavior];

連接(UIAttachmentBehavior)

連接就是讓一個(gè)物體的行為和移動(dòng)受另外一個(gè)物體的移動(dòng)事秀。使用連接效果要指定連接點(diǎn)彤断。效果大概如下:

在上面的效果演示圖中,我添加了一個(gè)pan手勢(shì)秽晚,然后取pan的坐標(biāo)點(diǎn)讓其成為籃球center,在連接效果的作用下瓦糟,足球會(huì)由于籃球的移動(dòng)而動(dòng),具體代碼如下:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.footballView,self.basketballView]];
[collisionBehavior setCollisionMode:UICollisionBehaviorModeEverything];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
    
CGPoint basketballCenter = CGPointMake(self.basketballView.center.x, self.basketballView.center.y);
self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.basketballView attachedToAnchor:basketballCenter];
    
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:self.attachmentBehavior];
 
self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handAttachmentesture:)];
[self.view addGestureRecognizer:self.panGesture];

- (void)handAttachmentesture:(UIPanGestureRecognizer *)gesture{
    CGPoint gesturePoint = [gesture locationInView:self.view];
    self.basketballView.center = gesturePoint;
    [self.attachmentBehavior setAnchorPoint:gesturePoint];
}

彈簧

彈簧效果應(yīng)該都懂赴蝇,先看看效果:

彈簧效果其實(shí)是在連接效果上實(shí)現(xiàn)的菩浙,恰當(dāng)設(shè)置連接效果的Frequency,Damping這二個(gè)屬性后就可以達(dá)到彈簧的效果了,在上面的代碼加上:

[self.attachmentBehavior setFrequency:1.0f];//振動(dòng)頻率
[self.attachmentBehavior setDamping:0.1f];//熨平動(dòng)畫(huà)的峰值

吸附(UISnapBehavior)

吸附效果有點(diǎn)像磁鐵吸鐵塊一樣句伶,只要我們指定一個(gè)點(diǎn)劲蜻,具有吸附效果的物體就有了被磁鐵吸過(guò)去的效果了。

我們?cè)谄聊簧现付ㄒ粋€(gè)tap手勢(shì)考余,講tap后的點(diǎn)作為磁鐵,代碼:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handTapGesture:)];
[self.view addGestureRecognizer:self.tapGesture];

- (void)handTapGesture:(UITapGestureRecognizer *)gesture{
    CGPoint point = [gesture locationInView:self.view];
    if (self.snapBehavior == nil) {
        self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.footballView snapToPoint:point];
        self.snapBehavior.damping = 0.75;
    }
    [self.animator addBehavior:self.snapBehavior];
}

推力

推力指得是可以對(duì)物體施加推力先嬉,效果:

我用了一個(gè)tap手勢(shì)作為施加推力的源,代碼如下:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    
UICollisionBehavior * collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.footballView]];
[self.animator addBehavior:collisionBehavior];
    
UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.footballView] mode:UIPushBehaviorModeInstantaneous];
pushBehavior.angle = 0.0;
pushBehavior.magnitude = 0.;
    
self.pushBehavior = pushBehavior;
[self.animator addBehavior:self.pushBehavior];
    
self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handTapGesture:)];
[self.view addGestureRecognizer:self.tapGesture];

- (void)handTapGesture:(UITapGestureRecognizer *)gesture{
    CGPoint point = [gesture locationInView:self.view];
    CGPoint origin = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
    CGFloat distance = sqrtf(powf(point.x-origin.x, 2.0) + powf(point.y-origin.y, 2.0));
    CGFloat angle = atan2(point.y-origin.y, point.x-origin.x);
    distance = MIN(distance, 100.0);
    [self.pushBehavior setMagnitude:distance/100.0];
    [self.pushBehavior setAngle:angle];
    [self.pushBehavior setActive:true];
}

物體屬性

物體都有很多的屬性楚堤,通過(guò)對(duì)其配置疫蔓,可以達(dá)到不同的效果含懊,下面是一些常用的屬性:

屬性 描述
elasticity 表示與其他物體碰撞時(shí)的彈性,取值0-1衅胀,0表示沒(méi)有彈性岔乔,1表示反彈作用力與碰撞作用力相等
allowsRotation 指定物體在受力時(shí)是否會(huì)旋轉(zhuǎn),默認(rèn)YES
angularResistance 旋轉(zhuǎn)助力滚躯,值越大旋轉(zhuǎn)下降得越快雏门,取值為0-CGFLOAT_MAX
density 物體的密度,調(diào)整密度會(huì)影響重力和碰撞的效果掸掏。默認(rèn)情況下茁影,100x100的物體質(zhì)量為1,100x200為2
friction 物體之間的滑動(dòng)阻力丧凤,0表示沒(méi)有摩擦力募闲,1表示摩擦力很大
resistance 空氣阻力,取值為0-CGFLOAT_MAX息裸,0表示沒(méi)有空氣阻力蝇更,1表示一旦其他作用力消失,物體就會(huì)停止

總結(jié)

文章代碼Demo點(diǎn)這里
UIDynamicAnimator還有代理方法和其他的小方法,真正發(fā)揮它的作用力的是你的創(chuàng)意恃慧,有好的ideal就動(dòng)手?jǐn)]吧腿箩!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市姨裸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖腿时,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異饭宾,居然都是意外死亡批糟,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)看铆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)徽鼎,“玉大人,你說(shuō)我怎么就攤上這事弹惦》裼伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵棠隐,是天一觀的道長(zhǎng)石抡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)助泽,這世上最難降的妖魔是什么啰扛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任嚎京,我火速辦了婚禮,結(jié)果婚禮上隐解,老公的妹妹穿的比我還像新娘挖藏。我一直安慰自己,他們只是感情好厢漩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布膜眠。 她就那樣靜靜地躺著,像睡著了一般溜嗜。 火紅的嫁衣襯著肌膚如雪宵膨。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,775評(píng)論 1 307
  • 那天炸宵,我揣著相機(jī)與錄音辟躏,去河邊找鬼。 笑死土全,一個(gè)胖子當(dāng)著我的面吹牛捎琐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裹匙,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瑞凑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了概页?” 一聲冷哼從身側(cè)響起籽御,我...
    開(kāi)封第一講書(shū)人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惰匙,沒(méi)想到半個(gè)月后技掏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡项鬼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年哑梳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绘盟。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸠真,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奥此,到底是詐尸還是另有隱情弧哎,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布稚虎,位于F島的核電站撤嫩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蠢终。R本人自食惡果不足惜序攘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一茴她、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧程奠,春花似錦丈牢、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至距境,卻和暖如春申尼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垫桂。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工师幕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诬滩。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓霹粥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親疼鸟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子后控,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

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