1.什么是動(dòng)力系統(tǒng)(What is the UIKit Dynamics?)
動(dòng)力系統(tǒng)的引入埃脏,并不是替代CoreAnimation搪锣,而是對(duì)模擬現(xiàn)實(shí)世界物體運(yùn)動(dòng)的補(bǔ)充,比如彩掐,碰撞构舟,重力,懸掛等等堵幽。所以說狗超,UIKit動(dòng)力系統(tǒng)的引入,大大簡(jiǎn)化了一些交互動(dòng)畫(不需要自己實(shí)現(xiàn)一些模擬現(xiàn)實(shí)世界物理動(dòng)力系統(tǒng)的動(dòng)畫)朴下,豐富了UI設(shè)計(jì)努咐。
2.動(dòng)力系統(tǒng)怎么使用(How to use it?)
UIKit動(dòng)力系統(tǒng)結(jié)構(gòu)如下:
總的來說,先要注冊(cè)UI系統(tǒng)體系桐猬,也就是類似于二維的坐標(biāo)系麦撵,然后添加所需的行為以及行為的作用物體,然后該物體就能在設(shè)定的坐標(biāo)體系里,根據(jù)所添加的行為運(yùn)動(dòng)免胃。
光說不練乃是紙上談兵音五,沒有成效。下面分解動(dòng)力系統(tǒng)所包含的幾類運(yùn)動(dòng)羔沙。
UIGravityBehavior
重力躺涝,這個(gè)大家應(yīng)該都很熟悉了。我們每天都能感受到它的存在扼雏,所謂腳踏實(shí)地就是這種感覺坚嗜。小時(shí)候,大家應(yīng)該都有過從高處把一些物體扔下來诗充,或者直接讓它坐自由落體運(yùn)動(dòng)苍蔬,相似的,這個(gè)Gravity也是模擬重力行為蝴蜓,下面直接上代碼碟绑。
myAnimator = [[UIDynamicAnimator alloc] initWithReferenceView: self];
myAnimator.delegate = self;
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems: @[ball]];
[myAnimator addBehavior: gravityBehavior];
1.UIDynamicAnimator就是一個(gè)播放者,容器茎匠。一個(gè)容納動(dòng)力系統(tǒng)的環(huán)境格仲,而referenceView就是該環(huán)境的坐標(biāo)系,物體運(yùn)動(dòng)的參照系诵冒。
- gravityBehavior凯肋,初始化一個(gè)重力行為,行為的受力物體是ball(只要實(shí)現(xiàn)UIDynamicItem接口的類都能作為受力物體汽馋,如侮东,View和UICollectionViewLayoutAttributes)。
- 將這個(gè)行為添加到UIDynamicAnimator上面就行了豹芯。
- 顯示效果的Demo以及代碼下載在最后苗桂。
UICollisionBehavior
碰撞行為,最直接的感受就是告组,玩彈珠,一顆彈珠可以被另一顆彈珠彈射到很遠(yuǎn)的地方癌佩,原理就是碰撞產(chǎn)生了一個(gè)反方向的作用力木缝,遠(yuǎn)離事故發(fā)生地。廢話也不多說围辙,直接上代碼:
myAnimator = [[UIDynamicAnimator alloc] initWithReferenceView: self];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems: ballsArray2]; collision.translatesReferenceBoundsIntoBoundary = YES;
collision.collisionDelegate = self;
[myAnimator addBehavior: collision];
1.和重力行為一樣我碟,也要先初始化一個(gè)容器myAnimator。
2.添加碰撞行為collision姚建,collision.translatesReferenceBoundsIntoBoundary的屬性是否設(shè)置以參考View的邊界為碰撞邊界矫俺,我們這里選擇YES。
3.除了設(shè)置參考View的邊界為碰撞邊界外,還可以自己設(shè)定邊界厘托,使用- addBoundaryWithIdentifier: forPath:或者addBoundaryWithIdentifier: fromPoint: toPoint:方法可以自己設(shè)定碰撞邊界的范圍友雳。
4。最后铅匹,也需要把collision添加到myAnimator上押赊。
UIAttachmentBehavior
描述一個(gè)物體和一個(gè)錨點(diǎn)或者另一個(gè)物體的連接,可以是彈性的包斑,也可以是非彈性的連接流礁。直接上代碼:
UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem: square offsetFromCenter: UIOffsetMake(0, - 40) attachedToAnchor: anchor];
attachmentBehavior.length = 100;
attachmentBehavior.damping = 0.3;
[myAnimator addBehavior: attachmentBehavior];
1.物體默認(rèn)的錨點(diǎn)在中心,可以設(shè)置偏移罗丰。
2.步驟也是和其它得行為一樣神帅,設(shè)置參數(shù),把該行為添加到myAnimator上萌抵。
3.更多的方法和屬性找御,請(qǐng)自行參考蘋果官方文檔。
UISnapBehavior
吸附行為谜嫉,將UIView通過動(dòng)畫吸附到某個(gè)點(diǎn)上萎坷。API非常簡(jiǎn)單,看下面代碼就懂了沐兰。
UISnapBehavior *snapBehavior = [[UISnapBehavior alloc] initWithItem: ballView snapToPoint: centerBall.center];
snapBehavior.damping = 0.4;
[myAnimator addBehavior: snapBehavior];
UIPushBehavior
推動(dòng)力哆档,可以理解為向一個(gè)物體施加一個(gè)作用力,可以是持續(xù)的住闯,也可以是瞬間的沖擊瓜浸。
UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems: @[square] mode: UIPushBehaviorModeInstantaneous];
pushBehavior.pushDirection = CGVectorMake(velocity.x / 1000, velocity.y / 1000);
[myAnimator addBehavior: pushBehavior];
UIDynamicItemBehavior
這其實(shí)不是一種行為,我的理解是對(duì)于將要進(jìn)行各種行為的物體一些參數(shù)上面的設(shè)置比原,比如插佛,彈力,震蕩頻率量窘,密度等等雇寇。
UIDynamicItemBehavior *behavior3 = [[UIDynamicItemBehavior alloc] initWithItems: @[ballsArray2[2]]];
behavior3.elasticity = 0.5;
behavior3.friction = 0.3;
behavior3.resistance = 0.3;
[myAnimator addBehavior: behavior3];
3.組合(Group)
所有的行為都可以組合起來,如碰撞和重力蚌铜,可以類似于物體做自由落體運(yùn)動(dòng)锨侯,然后和地面碰撞。代碼如下:
myAnimator = [[UIDynamicAnimator alloc] initWithReferenceView: self];
//重力行為
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems: @[ball]];
[myAnimator addBehavior: gravity];
//碰撞行為
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems: @[ball]];
collision.translatesReferenceBoundsIntoBoundary = YES;
collision.collisionDelegate = self;
[myAnimator addBehavior: collision];
//設(shè)置物體的一些相關(guān)的參數(shù)
UIDynamicItemBehavior *behavior = [[UIDynamicItemBehavior alloc] init];
behavior.elasticity = 0.8;
behavior.friction = 0.2;
behavior.resistance = 0.3;
behavior.density = 0.5;
behavior.angularResistance = 0.2;
[behavior addItem: ball];
[myAnimator addBehavior: behavior];
4.自定義行為(DIY)
1.將官方的行為打包
- 繼承UIDynamicBehavior(一個(gè)抽象類)
- 實(shí)現(xiàn)添加組合行為的方法冬殃,最好和官方的保持一致囚痴,比如:initWithItems:,在里面調(diào)用addChildBehavior:方法添加需要組合的行為
- 初始化該繼承類审葬,然后使用
@interface GravityWithCollisionBehavior : UIDynamicBehavior
- (instancetype)initWithItems: (NSArray *)items;
@end
@implementation GravityWithCollisionBehavior
- (instancetype)initWithItems: (NSArray *)items {
self = [super init];
if (self) {
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems: items];
[self addChildBehavior: gravityBehavior];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems: items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[self addChildBehavior: collisionBehavior];
}
return self;
}
@end
2.完全自定義行為
UIDynamicBehavior里提供了一個(gè)@property(nonatomic, copy) void (^action)(void)
深滚,animator將會(huì)在行為發(fā)生期間奕谭,每一步都調(diào)用這個(gè)block。也就是說痴荐,你想自定義行為就得在這里寫自己的一些代碼血柳。具體就是在這個(gè)block中向所有的item詢問它們當(dāng)前的center和transform狀態(tài),然后經(jīng)過計(jì)算蹬昌,把新的值賦予相應(yīng)的item混驰,從而該改變它們?cè)谄聊簧系奈恢茫笮≡矸罚嵌绕苷ィ较虻鹊取?/p>
5.終結(jié)(Summary)
總的來說,iOS7引進(jìn)的這套動(dòng)力系統(tǒng)明刷,大大豐富了我們動(dòng)畫表達(dá)婴栽,但是,該系統(tǒng)有著一些限制辈末,會(huì)消耗一定的CPU資源愚争,并且,當(dāng)它們被添加到動(dòng)畫系統(tǒng)后挤聘,只能通過動(dòng)畫系統(tǒng)改變位置轰枝,而外部對(duì)于UIDynamicsItem的center,transform等設(shè)定是被忽略的,除此之外组去,該系統(tǒng)也沒有現(xiàn)實(shí)世界那么精確鞍陨,當(dāng)計(jì)算迭代無法得到有效解的時(shí)候,動(dòng)畫將無法得到正確的呈現(xiàn)从隆,所以诚撵,不要將動(dòng)力系統(tǒng)神化。