UIDynamic物理仿真 下面介绍一下各种属性
一、简单介绍
1.什么是UIDynamic
UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架,可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象
如:重力、弹性碰撞等现象
2.物理引擎的价值
广泛用于游戏开发,经典成功案例是“愤怒的小鸟”
让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果
提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏
3.知名的2D物理引擎
Box2d
Chipmunk
二、使用步骤
要想使用UIDynamic来实现物理仿真效果,大致的步骤如下
(1)创建一个物理仿真器(顺便设置仿真范围)
(2)创建相应的物理仿真行为(顺便添加物理仿真元素)
(3)将物理仿真行为添加到物理仿真器中 开始仿真
三、相关说明
1.三个概念
(1)谁要进行物理仿真?
物理仿真元素(Dynamic Item)
(2)执行怎样的物理仿真效果?怎样的动画效果?
物理仿真行为(Dynamic Behavior)
(3)让物理仿真元素执行具体的物理仿真行为
物理仿真器(Dynamic Animator)
2.物理仿真元素
注意:
不是任何对象都能做物理仿真元素
不是任何对象都能进行物理仿真
物理仿真元素要素:
任何遵守了UIDynamicItem协议的对象
UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真
UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议
四、物理仿真器 ------------UIDynamicAnimator
须知:它可以让物理仿真元素执行物理仿真行为,它是UIDynamicAnimator类型的对象
物理仿真器属性方法说明
(1)UIDynamicAnimator的常见方法
- (instancetype)initWithReferenceView:(UIView *)view; //初始化一个仿真器。view参数:是一个参照视图,表示物理仿真的范围
- (void)addBehavior:(UIDynamicBehavior *)behavior; //添加1个物理仿真行为
- (void)removeBehavior:(UIDynamicBehavior *)behavior; //移除1个物理仿真行为
- (void)removeAllBehaviors; //移除之前添加过的所有物理仿真行为
- (NSArray<id<UIDynamicItem>> *)itemsInRect:(CGRect)rect;
- (void)updateItemUsingCurrentState:(id <UIDynamicItem>)item;//(更新dynamic item在UIDynamicAnimator内部的代表的状态),dynamic item被加入到UIDynamicAnimator后,你更改了dynamic item的状态,你应该使用这个方法更新dynamic item的状态。
- (NSTimeInterval)elapsedTime; //返回动画开始到现在的时间间隔
(2)UIDynamicAnimator的常见属性
@property (nonatomic, readonly) UIView* referenceView; //参照视图
@property (nonatomic, readonly, copy) NSArray* behaviors;//添加到物理仿真器中的所有物理仿真行为
@property (nonatomic, readonly, getter = isRunning) BOOL running;//是否正在进行物理仿真
@property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;//代理对象(能监听物理仿真器的仿真过程,比如开始和结束){
@optional
- (void)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator;
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator;
}
(3)UIDynamicAnimator中的Collection View Additions:
• - (UICollectionViewLayoutAttributes *)layoutAttributesForCellAtIndexPath:(NSIndexPath *)indexPath;//返回指定位置collection view cell的布局属性
• - (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath; //返回indexPath位置上collection view cell的指定(用decorationViewKind指定)decorationView的布局属性。
• - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;//返回indexPath位置上collection view cell的指定(用kind指定)SupplementaryView的布局属性。
五、物理仿真行为 ------------UIDynamicBehavior
(1)UIDynamic提供了以下几种物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:捕捉行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为
(2)物理仿真行为须知
上述所有物理仿真行为都继承自UIDynamicBehavior,所有的UIDynamicBehavior都可以独立进行,组合使用多种行为时,可以实现一些比较复杂的效果。
(3)UIDynamicBehavior属性方法介绍
- (void)addChildBehavior:(UIDynamicBehavior *)behavior;
- (void)removeChildBehavior:(UIDynamicBehavior *)behavior;
@property (nonatomic, readonly, copy) NSArray<__kindof UIDynamicBehavior *> *childBehaviors;
@property (nullable, nonatomic,copy) void (^action)(void);
- (void)willMoveToAnimator:(nullable UIDynamicAnimator *)dynamicAnimator;
@property (nullable, nonatomic, readonly) UIDynamicAnimator *dynamicAnimator;
UIGravityBehavior(重力)
- (instancetype)initWithItems:(NSArray<id <UIDynamicItem>> *)items;//初始化
- (void)addItem:(id <UIDynamicItem>)item;//添加
- (void)removeItem:(id <UIDynamicItem>)item;//移除
@property (nonatomic, readonly, copy) NSArray<id <UIDynamicItem>> *items;//行为数组
@property (readwrite, nonatomic) CGVector gravityDirection;//运动方向,默认是(0.0f, 1.0f)。dx为-1.0f时向左运动,dy为-1.0时向上运动,所以根据0.0~1.0可以定位所有的方向。
@property (readwrite, nonatomic) CGFloat angle;//重力方向(是一个角度,以x轴正方向为0°,顺时针正数,逆时针负数)
@property (readwrite, nonatomic) CGFloat magnitude;/量级(用来控制加速度,1.0代表加速度是1000 points /second²)可以去负数
- (void)setAngle:(CGFloat)angle magnitude:(CGFloat)magnitude;//
UICollisionBehavior(碰撞)
- (instancetype)initWithItems:(NSArray<id <UIDynamicItem>> *)items;//初始化
- (void)addItem:(id <UIDynamicItem>)item;//添加
- (void)removeItem:(id <UIDynamicItem>)item;//移除
@property (nonatomic, readonly, copy) NSArray<id <UIDynamicItem>> *items;//碰撞行为数组
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;//碰撞模式(分三种,
UICollisionBehaviorModeItems = 1 << 0,元素碰撞
UICollisionBehaviorModeBoundaries = 1 << 1, 边界碰撞
UICollisionBehaviorModeEverything = NSUIntegerMax 全体碰撞)
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;//是否以参照视图的bounds为边界
@property (nullable, nonatomic, weak, readwrite) id <UICollisionBehaviorDelegate> collisionDelegate;//代理
{-------------------------------------代理方法
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;
- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;
// The identifier of a boundary created with translatesReferenceBoundsIntoBoundary or setTranslatesReferenceBoundsIntoBoundaryWithInsets is nil
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p;
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier;
}
- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;//
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath *)bezierPath;//添加一个path作为碰撞边界
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;//添加一条线作为碰撞边界
- (nullable UIBezierPath *)boundaryWithIdentifier:(id <NSCopying>)identifier;//
- (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier; //移除某个的
@property (nullable, nonatomic, readonly, copy) NSArray<id <NSCopying>> *boundaryIdentifiers;//
- (void)removeAllBoundaries;//移除所有
UISnapBehavior(捕捉)
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;//初始化
@property (nonatomic, assign) CGPoint snapPoint;
@property (nonatomic, assign) CGFloat damping;//用于减幅、减震(取值范围是0.0 ~ 1.0,值越大,震动幅度越小)
注意:
//2.执行捕捉行为
43 //注意:这个控件只能用在一个仿真行为上,如果要拥有持续的仿真行为,那么需要把之前的所有仿真行为删除
44 //删除之前的所有仿真行为
45 [self.animator removeAllBehaviors];
46 [self.animator addBehavior:snap];
UIPushBehavior(推动)
- (instancetype)initWithItems:(NSArray<id <UIDynamicItem>> *)items mode:(UIPushBehaviorMode)mode;
- (void)addItem:(id <UIDynamicItem>)item;
- (void)removeItem:(id <UIDynamicItem>)item;
@property (nonatomic, readonly, copy) NSArray<id <UIDynamicItem>> *items;
- (UIOffset)targetOffsetFromCenterForItem:(id <UIDynamicItem>)item;//
- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;//
@property (nonatomic, readonly) UIPushBehaviorMode mode;//{
UIPushBehaviorModeContinuous,//持续的力
UIPushBehaviorModeInstantaneous //一次性的力
}
@property (nonatomic, readwrite) BOOL active;//默认值是YES,将其设置为NO,可以将行为停止。
@property (readwrite, nonatomic) CGFloat angle;//角度
@property (readwrite, nonatomic) CGFloat magnitude;//加速度
@property (readwrite, nonatomic) CGVector pushDirection;//运动方向
- (void)setAngle:(CGFloat)angle magnitude:(CGFloat)magnitude;//
UIAttachmentBehavior(附着)
- (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;
- (instancetype)initWithItem:(id <UIDynamicItem>)item offsetFromCenter:(UIOffset)offset attachedToAnchor:(CGPoint)point;
- (instancetype)initWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2;
- (instancetype)initWithItem:(id <UIDynamicItem>)item1 offsetFromCenter:(UIOffset)offset1 attachedToItem:(id <UIDynamicItem>)item2 offsetFromCenter:(UIOffset)offset2;
+ (instancetype)slidingAttachmentWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2 attachmentAnchor:(CGPoint)point axisOfTranslation:(CGVector)axis;
+ (instancetype)slidingAttachmentWithItem:(id <UIDynamicItem>)item attachmentAnchor:(CGPoint)point axisOfTranslation:(CGVector)axis;
+ (instancetype)limitAttachmentWithItem:(id <UIDynamicItem>)item1 offsetFromCenter:(UIOffset)offset1 attachedToItem:(id <UIDynamicItem>)item2 offsetFromCenter:(UIOffset)offset2;
+ (instancetype)fixedAttachmentWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2 attachmentAnchor:(CGPoint)point;
+ (instancetype)pinAttachmentWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2 attachmentAnchor:(CGPoint)point;
@property (nonatomic, readonly, copy) NSArray<id <UIDynamicItem>> *items;
@property (readonly, nonatomic) UIAttachmentBehaviorType attachedBehaviorType;//{
UIAttachmentBehaviorTypeItems,
UIAttachmentBehaviorTypeAnchor
}
@property (readwrite, nonatomic) CGPoint anchorPoint;//
@property (readwrite, nonatomic) CGFloat length; //
@property (readwrite, nonatomic) CGFloat damping; //振幅
@property (readwrite, nonatomic) CGFloat frequency; //频率
@property (readwrite, nonatomic) CGFloat frictionTorque;//
@property (readwrite, nonatomic) UIFloatRange attachmentRange; //
UIDynamicItemBehavior:动力元素行为
- (instancetype)initWithItems:(NSArray<id <UIDynamicItem>> *)items;//
- (void)addItem:(id <UIDynamicItem>)item;//
- (void)removeItem:(id <UIDynamicItem>)item;//
@property (nonatomic, readonly, copy) NSArray<id <UIDynamicItem>> *items;//
@property (readwrite, nonatomic) CGFloat elasticity; //(弹性系数)决定了碰撞的弹性程度,比如碰撞时物体的弹性
@property (readwrite, nonatomic) CGFloat friction;//(摩擦系数)决定了沿接触面滑动时的摩擦力大小
@property (readwrite, nonatomic) CGFloat density;//(密度) 跟size结合使用,计算物体的总质量。质量越大,物体加速或减速就越困难
@property (readwrite, nonatomic) CGFloat resistance;//(阻力):决定线性移动的阻力大小,与摩擦系数不同,摩擦系数只作用于滑动运动
@property (readwrite, nonatomic) CGFloat angularResistance;//(角阻力) :决定旋转运动时的阻力大小
@property (readwrite, nonatomic) CGFloat charge;//
@property (nonatomic, getter = isAnchored) BOOL anchored;//
@property (readwrite, nonatomic) BOOL allowsRotation; //(允许旋转):这个属性很有意思,它在真实的物理世界没有对应的模型。设置这个属性为 NO 物体就完全不会转动,而无论施加多大的转动力
- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;//
- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;//
- (void)addAngularVelocity:(CGFloat)velocity forItem:(id <UIDynamicItem>)item;//
- (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;/
网友评论