UIKit Dynamics (一) 概述
UIKit Dynamics (二) 重力
UIKit Dynamics (三) 碰撞
UIKit Dynamics (四) 急停
UIKit Dynamics (五) 施力
這篇文章中將討論 UIKit Dynamics 中的碰撞效果,本文使用的 demo 中添加了重力來使方塊下落并碰撞只是為了方便,實際中不使用重力通過其他方式進行碰撞也是可以的。
UICollisionBehavior
Collision 為一組 DynamicItem 提供了碰撞檢測,一組中的每個 item 之間都會在邊界處產生碰撞效果。即看起來每個 item 有了體積,不會像正常情況下重疊起來。
使用
UICollisionBehavior 通過一個數組進行初始化,數組中的元素都將遵循碰撞規則,并添加到一個 animator 中就完成了碰撞的創建。
_collisionBehavior = [[UICollisionBehavior alloc] initWithItems:_boxes];
[_animator addBehavior:_collisionBehavior];
配置
UICollisionBehavior 中有如下比較重要的屬性和方法
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath *)bezierPath;
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;
兩個添加碰撞體的方法,第一種是通過 UIBezierPath 添加比如圓形扇形曲線等圖形,第二種是直接添加兩點連成的直線。
而 translatesReferenceBoundsIntoBoundary 這個屬性非常方便,當 UICollisionBehavior 添加到 UIDynamicAnimator 中時,可以將 animator 中的 reference view 直接轉換為碰撞體,即自動添加了一個碰撞邊界,collision behavior 中的所有碰撞體都會撞到邊界反彈,避免了碰撞出界同時不需要麻煩地單獨為外邊界設置碰撞。
// create boundary with bezier path
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 200, 40, 40)];
[_collisionBehavior addBoundaryWithIdentifier:@1 forPath:path];
// create boundary with line
[_collisionBehavior addBoundaryWithIdentifier:@2 fromPoint:CGPointMake(90, 300) toPoint:CGPointMake(130, 300)];
// create boundary with curve
UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 230) radius:40 startAngle:0 endAngle:M_PI * 0.75 clockwise:YES];
[path2 addLineToPoint:CGPointMake(240, 230)];
[path2 closePath];
[_collisionBehavior addBoundaryWithIdentifier:@3 forPath:path2];
// set reference view collided
_collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_collisionBehavior];
關于碰撞還有一點,雖然碰撞時模擬現實的物理效果,可是在程序中我們可以構建多個 UICollisionBehavior 并為每個碰撞規則添加多個 item,但遵循不同碰撞規則的 item 之間不會相互碰撞。
// cretae collision behavior for red boxes and blue boxes
_redCollisionBehavior = [[UICollisionBehavior alloc] initWithItems:_redBoxes];
_redCollisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_redCollisionBehavior];
_blueCollisionBehavior = [[UICollisionBehavior alloc] initWithItems:_blueBoxes];
_blueCollisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_blueCollisionBehavior];
紅色方塊和藍色方塊分別遵循不同的碰撞規則。紅色與紅色,藍色與藍色仍然會相互碰撞,但紅色與藍色則會直接重疊。
本文 demo 是 Collision 和 Collision + Multiple 頁面,項目地址