1.7附着行为UIAttachmentBehavior
(一)附着行为UIAttachmentBehavior作用
作用:附着行为描述的是一个试图到一个锚点或者一个试图到一个试图连接情况,可以模拟刚性连接和弹性连接多个view之间设定多个UIAttachmentBehavior,可以模拟多物体连接.
(二)常用属性和方法
// 附着行为作用的物理学元素
@property (nonatomic, readonly, copy) NSArray<id <UIDynamicItem>> *items;
// 附着行为的类型
@property (readonly, nonatomic) UIAttachmentBehaviorType attachedBehaviorType;
// 附着点
@property (readwrite, nonatomic) CGPoint anchorPoint;
// 两个附着点之间的距离长度
@property (readwrite, nonatomic) CGFloat length;
// 附着点之间的振幅 从0.0到1.0 值越大振幅越大,反之越小
@property (readwrite, nonatomic) CGFloat damping; // 1: critical damping
// 频率 取值范围0.0~1.0 值越大弹力越大,反之越小
@property (readwrite, nonatomic) CGFloat frequency; // in Hertz
@property (readwrite, nonatomic) CGFloat frictionTorque
// 初始化一个视图和点之间的附着行为
- (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
示例代码:
// 自定义控制器view
@interface BGView : UIView
@property (nonatomic, assign) CGPoint start;
@property (nonatomic, assign) CGPoint end;
@end
@implementation BGView
// 在控制器view上绘制刚性附着的那个线
- (void)drawRect:(CGRect)rect{
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:self.start];
[path addLineToPoint:self.end];
[path stroke];
}
@end
@interface ViewController ()
@property (nonatomic, weak) UIView *redView;
@property (nonatomic, strong) UIDynamicAnimator *animator;
@property (nonatomic, strong) UIAttachmentBehavior *att;
@end
@implementation ViewController
- (void)loadView{
self.view = [[BGView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view.backgroundColor = [UIColor whiteColor];
}
- (void)viewDidLoad {
[super viewDidLoad];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
redView.backgroundColor = [UIColor redColor];
redView.alpha = 0.5;
self.redView = redView;
[self.view addSubview:redView];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 获取触摸对象
UITouch *t = touches.anyObject;
// 获取触摸点
CGPoint p = [t locationInView:t.view];
// 1.创建动画者对象
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
// 2.创建动画行为
// self.att = [[UIAttachmentBehavior alloc] initWithItem:self.redView attachedToAnchor:p];
// 创建一个带偏移量的附着行为
self.att = [[UIAttachmentBehavior alloc] initWithItem:self.redView offsetFromCenter:UIOffsetMake(30, 30) attachedToAnchor:p];
self.att.length = 100;
// 设置下面两个属性后就变成弹性附着
self.att.damping = 1;
self.att.frequency = 1;
// 3.添加行为到动画者对象
[self.animator addBehavior:self.att];
// 创建重力行为
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
// 添加重力行为到动画者对象
[self.animator addBehavior:gravity];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 获取触摸对象
UITouch *t = touches.anyObject;
// 获取触摸点
CGPoint p = [t locationInView:t.view];
self.att.anchorPoint = p;
// block引用self是一个强引用,需要声明一个weak的self在block中使用,这样就不会提示警告
__weak ViewController *weakVC = self;
self.att.action = ^{
BGView *bgView = (BGView *)self.view;
bgView.start = self.redView.center;
bgView.end = p;
[bgView setNeedsDisplay];
};
}
@end