文章已遷移到:limingjie.net传藏,請移步到http://limingjie.net/2016/11/07/iOS%20UIKit%E7%89%A9%E7%90%86%E5%BC%95%E6%93%8E%EF%BC%88%E4%B8%80%EF%BC%89%E4%BB%8B%E7%BB%8D/
關注文章最新更新
前言
從iOS7
開始UIKit
框架中添加了力學引擎煤率,我們可以使視圖通過力學引擎驅(qū)動而具有真實的物理運動效果篱瞎。
如果你想做一個類似摩拜單車app中貼紙的小球碰撞效果,我相信這一系列文章肯定會對你有很大幫助的桦沉。
框架結構
-
UIDynamicAnimator
UIDynamicAnimator
是為動態(tài)元素提供力學相關功能和動畫,并為這些運動提供物理空間啥容。它是力學引擎和動態(tài)元素之間的媒介曲秉,這些元素通過物理行為(UIDynamicBehavior)
被添加到UIDynamicAnimator
中。 -
UIDynamicBehavior
UIDynamicBehavior
是給一個或多個動態(tài)元素參與的二維動畫賦予的行為熊赖。我們通常使用它的6個物理特征子類:
UIGravityBehavior(重力)
UICollisionBehavior(碰撞)
UIAttachmentBehavior(吸附)
UIPushBehavior(推動)
UISnapBehavior(捕獲)
UIDynamicItemBehavior -
UIDynamicItem
UIDynamicItem
是參與力學運動的基本元素来屠,并且是遵守了UIDynamicItem
協(xié)議的對象,例如UIView
和UICollectionViewLayoutAttributes
。如果自定義對象也實現(xiàn)了UIDynamicItem
協(xié)議俱笛,也是可以使用的捆姜。
UIDynamicAnimator
詳細的介紹一下UIDynamicAnimator
- 構造方法
-(instancetype)initWithReferenceView:(UIView *)view NS_DESIGNATED_INITIALIZER;
根據(jù)NS_DESIGNATED_INITIALIZER
宏可以知道該方法是UIDynamicAnimator
指定的初始化方法。
構建代碼如下:
@interface ViewController ()
@property (nonatomic,strong) UIDynamicAnimator * animator;
@end
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
函數(shù)中的Reference View
參數(shù)是指_animator
所要實施力學動作的‘引用視圖’嫂粟,通俗的說就是運動元素所在的空間系娇未,_animator
上所有的力學行為的動態(tài)元素都將以該‘引用視圖’作為空間系進行物理運動。這里我們把viewController
中的self.view
設置為‘引用視圖’星虹。
注意:在我們構建
UIDynamicAnimator
對象時一定要被其它對象有效持有零抬,不然在arc
模式下將很快被自動釋放。
- 屬性
// 引用視圖 (只讀)
@property (nullable, nonatomic, readonly) UIView *referenceView;
// 添加的行為數(shù)組 (只讀)
@property (nonatomic, readonly, copy) NSArray<__kindof UIDynamicBehavior*> *behaviors;
// 是否正在運行 (只讀)
@property (nonatomic, readonly, getter = isRunning) BOOL running;
// 運行以來的時間間隔(只讀宽涌,注意編譯條件)
#if UIKIT_DEFINE_AS_PROPERTIES
@property (nonatomic, readonly) NSTimeInterval elapsedTime;
#else
-(NSTimeInterval)elapsedTime;
#endif
// 代理
@property (nullable, nonatomic, weak) id <UIDynamicAnimatorDelegate> delegate;
- 方法
// 添加行為
-(void)addBehavior:(UIDynamicBehavior *)behavior;
// 移除行為
-(void)removeBehavior:(UIDynamicBehavior *)behavior;
// 移除所有行為
-(void)removeAllBehaviors;
// 返回指定矩形區(qū)域中的動態(tài)項目
-(NSArray<id<UIDynamicItem>> *)itemsInRect:(CGRect)rect;
// 在UIDynamicAnimator中更新我們已經(jīng)修改的動態(tài)項目
-(void)updateItemUsingCurrentState:(id <UIDynamicItem>)item;
- 代理(UIDynamicAnimatorDelegate)
@optional
// 當dynamicAnimator將要恢復調(diào)用
-(void)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator;
// 當dynamicAnimator已經(jīng)暫停調(diào)用
-(void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator;
UIDynamicBehavior
在通常情況下我們不會直接使用UIDynamicBehavior
類平夜,而是使用它的子類們。在開始介紹它的子類前卸亮,先來看看UIDynamicBehavior
作為父類的一些屬性和方法:
// 添加一個自定義行為子類
- (void)addChildBehavior:(UIDynamicBehavior *)behavior;
// 移除一個自定義行為子類
- (void)removeChildBehavior:(UIDynamicBehavior *)behavior;
// 當一個動態(tài)行為被添加或移除忽妒,會回調(diào)該函數(shù)
- (void)willMoveToAnimator:(nullable UIDynamicAnimator *)dynamicAnimator;
// 子行為 (只讀)
@property (nonatomic, readonly, copy) NSArray<__kindof UIDynamicBehavior *> *childBehaviors;
// 在運行時調(diào)用的每一個動畫步驟的block形式動作代碼
@property (nullable, nonatomic,copy) void (^action)(void);
// 所屬的dynamicAnimator
@property (nullable, nonatomic, readonly) UIDynamicAnimator *dynamicAnimator;
UIDynamicItem
詳細介紹一下UIDynamicItem
協(xié)議的屬性:
// 中心
@property (nonatomic, readwrite) CGPoint center;
// 實時范圍
@property (nonatomic, readonly) CGRect bounds;
// 旋轉(zhuǎn)狀態(tài)
@property (nonatomic, readwrite) CGAffineTransform transform;
@optional
/**
元素碰撞邊界的形狀類型
該參數(shù)用來獲得元素以何種形式進行碰撞
默認為UIDynamicItemCollisionBoundsTypeRectangle
*/
@property (nonatomic, readonly) UIDynamicItemCollisionBoundsType collisionBoundsType NS_AVAILABLE_IOS(9_0);
typedef NS_ENUM(NSUInteger, UIDynamicItemCollisionBoundsType) {
// 矩形碰撞邊界
UIDynamicItemCollisionBoundsTypeRectangle,
// 橢圓形碰撞邊界,橢圓的形狀是由元素的寬度和高度決定
UIDynamicItemCollisionBoundsTypeEllipse,
// 基于路徑碰撞邊界兼贸。這種類型的形狀是一個UIBezierPath對象存儲在元素的collisionBoundingPath屬性中段直。
UIDynamicItemCollisionBoundsTypePath
} NS_ENUM_AVAILABLE_IOS(9_0);
/**
碰撞路徑
該路徑必須是一個凸的多邊形圍繞而成,并且沒有自身的交叉
(0,0) 代表路徑的中心
(翻譯自官方文檔)
*/
@property (nonatomic, readonly) UIBezierPath *collisionBoundingPath NS_AVAILABLE_IOS(9_0);
代碼補充:
補充演示中的代碼溶诞,方便后續(xù)文章的理解:
_dynamicItem1View = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
_dynamicItem1View.backgroundColor = [UIColor blueColor];
_dynamicItem1View.layer.cornerRadius = 25;
[self.view addSubview:_dynamicItem1View];
_dynamicItem2View = [[UIView alloc] initWithFrame:CGRectMake(160, 250, 100, 100)];
_dynamicItem2View.backgroundColor = [UIColor blackColor];
_dynamicItem2View.layer.cornerRadius = 50;
[referenceView addSubview:_dynamicItem2View];
iOS UIKit動力學(二)重力(UIGravityBehavior)
iOS UIKit動力學(三)碰撞(UICollisionBehavior)
iOS UIKit動力學(四)吸附(UIAttachmentBehavior)
iOS UIKit動力學(五)推動(UIPushBehavior)
iOS UIKit動力學(六)捕獲(UISnapBehavior)
iOS UIKit動力學(七)其它動力學配置(UIDynamicItemBehavior)
版權聲明:出自MajorLMJ技術博客的原創(chuàng)作品 鸯檬,轉(zhuǎn)載時必須注明出處及相應鏈接!