5.5 iOS 碰撞行为UICollisionBehavior

1.5碰撞行为UICollisionBehavior

(一)碰撞行为UICollisionBehavior作用

作用:可以让物体之间实现碰撞效果,可以通过添加边界(boundary)将碰撞行为限定到某个区域.

(二)常用属性和方法

常用属性

@property (nonatomic, readonly, copy) NSArray> *items;
// 碰撞模式(有三种:元素碰撞,边界碰撞,全体碰撞)
// UICollisionBehaviorModeItems(元素碰撞),
// UICollisionBehaviorModeBoundaries(边界碰撞),
// UICollisionBehaviorModeEverything(全体碰撞).
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;
// 是否已参照视图的bounds为边界
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;
// 所有的碰撞边界
@property (nullable, nonatomic, readonly, copy) NSArray> *boundaryIdentifiers;
// 代理对象,可以监听碰撞的过程
@property (nullable, nonatomic, weak, readwrite) id  collisionDelegate;

常用方法


// 初始化一个碰撞行为,items:代表碰撞行为作用的所有仿真元素
- (instancetype)initWithItems:(NSArray> *)items;
// 添加一个仿真元素到碰撞行为
- (void)addItem:(id )item;
// 移除碰撞行为上的一个仿真元素
- (void)removeItem:(id )item;
// 设置碰撞行为参照视图的边界,并且设置内边距
- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;
// 添加一个路径作为碰撞行为的边界 identifier:边界ID bezierPath:使用UIBezierPath描述的一个边界
- (void)addBoundaryWithIdentifier:(id )identifier forPath:(UIBezierPath *)bezierPath;
// 添加一个从p1到p2的边界 identifier:边界ID
- (void)addBoundaryWithIdentifier:(id )identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;
// 根据指定ID返回一个使用UIBezierPath描述的路径
- (nullable UIBezierPath *)boundaryWithIdentifier:(id )identifier;
// 移除碰撞行为上指定ID为identifier的边界
- (void)removeBoundaryWithIdentifier:(id )identifier;
// 移除碰撞行为上的所有边界
- (void)removeAllBoundaries;

(三)UICollisionBehaviorDelegate

// 仿真元素和仿真元素碰撞开始 item1:仿真元素1 item2:仿真元素2 p:碰撞点
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id )item1 withItem:(id )item2 atPoint:(CGPoint)p;
// 仿真元素和仿真元素碰撞结束 item1:仿真元素1 item2:仿真元素2
- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id )item1 withItem:(id )item2;
// 仿真元素和边界碰撞开始 item:仿真元素 identifier:边界ID p:碰撞点
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id )item withBoundaryIdentifier:(nullable id )identifier atPoint:(CGPoint)p;
// 仿真元素和边界碰撞结束  item:仿真元素 identifier:边界ID
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id )item withBoundaryIdentifier:(nullable id )identifier;

示例代码:


// 控制器View
@interface RBView : UIView
@property (nonatomic, assign) CGRect rectR;

@end

@implementation RBView

- (void)drawRect:(CGRect)rect{
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(0, 300)];
    [path addLineToPoint:CGPointMake(200, 350)];
    [path stroke];
    [[UIBezierPath bezierPathWithRect:self.rectR] stroke];
}

@end

@interface RView : UIView
@property (nonatomic, assign) CGRect rectR;

@end

@implementation RView

- (void)drawRect:(CGRect)rect{
    [[UIBezierPath bezierPathWithRect:self.rectR] stroke];
}

@end


@interface ViewController ()
@property (nonatomic, weak) RView *redView;
@property (nonatomic, weak) UIView *blueView;
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end

@implementation ViewController

- (void)loadView{
    self.view = [[RBView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.view.backgroundColor = [UIColor whiteColor];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    RView *redView = [[RView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(180, [UIScreen mainScreen].bounds.size.height - 150, 50, 50)];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    self.redView = redView;
    self.blueView = blueView;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    // 1.创建仿真器
    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    
    // 2.创建物理仿真行为
    // 重力行为
    UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
    // 碰撞行为
    UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView,self.blueView]];
    // 设置边界碰撞
    collision.translatesReferenceBoundsIntoBoundary = YES;
    
    // 碰撞的action属性 实时监听碰撞过程
    collision.action = ^{
        // 需要强转
        RBView *rbView = (RBView *)self.view;
        rbView.rectR = self.redView.frame;
        [self.view setNeedsDisplay];
        NSLog(@"%@", NSStringFromCGRect(self.redView.frame));
        // 判断如果碰撞view的高大于105将颜色变成brownColor颜色 可以做一些加分什么的逻辑
        if (self.redView.frame.size.height > 105) {
            self.redView.backgroundColor = [UIColor brownColor];
        }else{
            self.redView.backgroundColor = [UIColor redColor];
        }
    };
    // 碰撞的模式
    collision.collisionMode = UICollisionBehaviorModeEverything;
    CGPoint startp = CGPointMake(0, 300);
    CGPoint endp = CGPointMake(200, 350);
    
    // 使用两点创建碰撞边界
    [collision addBoundaryWithIdentifier:@"key1" fromPoint:startp toPoint:endp];
    
    // 使用UIBezierPath创建碰撞边界
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.blueView.frame];
    [collision addBoundaryWithIdentifier:@"key" forPath:path];
    
    // 碰撞设置代理
    collision.collisionDelegate = self;
    
    // 3.将仿真行为添加到仿真器
    [self.animator addBehavior:gravity];
    [self.animator addBehavior:collision];
    
}
// 碰撞代理
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id)item withBoundaryIdentifier:(id)identifier atPoint:(CGPoint)p{
// 需要强制类型转化
    NSString *key = (NSString *)identifier;
    if ([key isEqualToString:@"key1"]) {
        self.redView.backgroundColor = [UIColor yellowColor];
    }else{
        self.redView.backgroundColor = [UIColor redColor];
    }
}

@end

你可能感兴趣的:(5.5 iOS 碰撞行为UICollisionBehavior)