简体   繁体   中英

Fixed UIView for collision

Is it possible to place an UIView fixed but as collision-object? In my example is a box-view falling down and collide with the floor-view. I want the floor-view to stay at it's place but it's moving after it's been hit by the box. How can I glue it in one place (I don't want to enlarge the object or use other objects than UIView (UIBezierPath etc)).

- (void)viewDidLoad {
    [super viewDidLoad];

    UIButton *start = [[UIButton alloc]initWithFrame:CGRectMake(200, 20, 40, 40)];
    start.backgroundColor = [UIColor redColor];
    [start addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside];
    [main addSubview:start];

    self.box1 = [[UIView alloc]initWithFrame:CGRectMake(50, 0, 20, 20)];
    self.box1.backgroundColor = [UIColor redColor];
    [main addSubview:self.box1];

    self.floor = [[UIView alloc]initWithFrame:CGRectMake(0, main.frame.size.height-20, main.frame.size.width, 200)];
    self.floor.backgroundColor = [UIColor lightGrayColor];
    [main addSubview:self.floor];  
}

- (void) start {
    self.animation = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
    UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[self.box1]];
    [self.animation addBehavior:gravity];

    UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[self.box1, self.floor]];
    [self.animation addBehavior:collision];
}

One solution to your problem (which is a quite simple setup) could be to create an UIView that will serve as a reference view. Set it's frame so the bottom of the view will be your floor. Then add your box as a subview for that reference view, add collision behaviour with translatesReferenceBoundsIntoBoundary set to YES and you have a box falling on the floor.

// Reference view
CGRect referenceFrame = CGRectMake(0, 0, 320, 500); // the floor will be at y = 500
UIView *referenceView = [[UIView alloc] initWithFrame:referenceFrame];
[self.view addSubview:referenceView];

// Box
CGRect boxFrame = CGRectMake(50, 50, 10, 10);
UIView *boxView = [[UIView alloc] initWithFrame:boxFrame];
boxView.backgroundColor = [UIColor redColor];

[referenceView addSubview:boxView];

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:referenceView];

// Gravity
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[boxView]];
[self.animator addBehavior:gravity];

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[boxView]];
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];

You can provide a pretty visual for the floor outside of referenceView

I used UIDynamicItemBehavior for my view and set the following property to be true.

@property(nonatomic, getter=isAnchored) BOOL anchored;

This locked the UIView in place. Do what you were doing above to add the item to the behavior and add the behavior to the animator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM