iOS UIKit动力学(一)基本介绍

文章已迁移到: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框架中添加了力学引擎,我们可以使视图通过力学引擎驱动而具有真实的物理运动效果。

如果你想做一个类似摩拜单车app中贴纸的小球碰撞效果,我相信这一系列文章肯定会对你有很大帮助的。

框架结构

  • UIDynamicAnimator
    UIDynamicAnimator是为动态元素提供力学相关功能和动画,并为这些运动提供物理空间。它是力学引擎和动态元素之间的媒介,这些元素通过物理行为(UIDynamicBehavior)被添加到UIDynamicAnimator中。
  • UIDynamicBehavior
    UIDynamicBehavior是给一个或多个动态元素参与的二维动画赋予的行为。我们通常使用它的6个物理特征子类:
    UIGravityBehavior(重力)
    UICollisionBehavior(碰撞)
    UIAttachmentBehavior(吸附)
    UIPushBehavior(推动)
    UISnapBehavior(捕获)
    UIDynamicItemBehavior
  • UIDynamicItem
    UIDynamicItem是参与力学运动的基本元素,并且是遵守了UIDynamicItem协议的对象,例如UIViewUICollectionViewLayoutAttributes。如果自定义对象也实现了UIDynamicItem协议,也是可以使用的。

UIDynamicAnimator

详细的介绍一下UIDynamicAnimator

  • 构造方法
-(instancetype)initWithReferenceView:(UIView *)view NS_DESIGNATED_INITIALIZER;

根据NS_DESIGNATED_INITIALIZER宏可以知道该方法是UIDynamicAnimator指定的初始化方法。
构建代码如下:

@interface ViewController ()
@property (nonatomic,strong) UIDynamicAnimator * animator;
@end
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

函数中的Reference View参数是指_animator所要实施力学动作的‘引用视图’,通俗的说就是运动元素所在的空间系,_animator上所有的力学行为的动态元素都将以该‘引用视图’作为空间系进行物理运动。这里我们把viewController中的self.view设置为‘引用视图’。

注意:在我们构建UIDynamicAnimator对象时一定要被其它对象有效持有,不然在arc模式下将很快被自动释放。

  • 属性
// 引用视图 (只读)
@property (nullable, nonatomic, readonly) UIView *referenceView;
// 添加的行为数组 (只读)
@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;
// 返回指定矩形区域中的动态项目
-(NSArray<id<UIDynamicItem>> *)itemsInRect:(CGRect)rect;
// 在UIDynamicAnimator中更新我们已经修改的动态项目
-(void)updateItemUsingCurrentState:(id <UIDynamicItem>)item;
  • 代理(UIDynamicAnimatorDelegate)
@optional
// 当dynamicAnimator将要恢复调用
-(void)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator;
// 当dynamicAnimator已经暂停调用
-(void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator;

UIDynamicBehavior

在通常情况下我们不会直接使用UIDynamicBehavior类,而是使用它的子类们。在开始介绍它的子类前,先来看看UIDynamicBehavior作为父类的一些属性和方法:

// 添加一个自定义行为子类
- (void)addChildBehavior:(UIDynamicBehavior *)behavior;
// 移除一个自定义行为子类
- (void)removeChildBehavior:(UIDynamicBehavior *)behavior;
// 当一个动态行为被添加或移除,会回调该函数
- (void)willMoveToAnimator:(nullable UIDynamicAnimator *)dynamicAnimator;
// 子行为 (只读)
@property (nonatomic, readonly, copy) NSArray<__kindof UIDynamicBehavior *> *childBehaviors;
// 在运行时调用的每一个动画步骤的block形式动作代码
@property (nullable, nonatomic,copy) void (^action)(void);
// 所属的dynamicAnimator
@property (nullable, nonatomic, readonly) UIDynamicAnimator *dynamicAnimator;

UIDynamicItem

详细介绍一下UIDynamicItem协议的属性:

// 中心
@property (nonatomic, readwrite) CGPoint center;
// 实时范围
@property (nonatomic, readonly) CGRect bounds;
// 旋转状态
@property (nonatomic, readwrite) CGAffineTransform transform;
@optional
/**
元素碰撞边界的形状类型
该参数用来获得元素以何种形式进行碰撞
默认为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);

代码补充:

补充演示中的代码,方便后续文章的理解:

_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技术博客的原创作品 ,转载时必须注明出处及相应链接!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • iOS 7增加了UIKit Dynamics库,其集成于UIKit框架中,将2D物理引擎引入了UIKit,提供了以...
    pro648阅读 2,797评论 2 14
  • 一、简单介绍 1.什么是UIDynamicUIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框...
    洛洛爱吃肉阅读 662评论 0 12
  • UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞,悬挂等效果,即将2...
    BarleyZ阅读 1,271评论 0 49
  • 本文中所有代码演示均有GitHub源码,点击下载 UIDynamic简介 简介:UIKit动力学最大的特点是将现实...
    si1ence阅读 10,215评论 8 79
  • 坐在车上,好无聊 形形色色的人都不像你 低头的,发呆的 竟然还有痴笑的 翻起随身携带的书 满满都是字 没有一幅插画...
    郭青年阅读 264评论 0 1