0
votes

I have two view controllers-- one is a main menu, the other is the game. The game has a box that drops, and if the user doesn't catch it, it falls off screen and resets at its original position at the top.

The app loads onto the main menu, and the first time I go to play, it works perfectly. I can play as many rounds as I want without problems. However, if I return to the main menu (modal segue) and then go back to the game, as soon as I try to start the animation again, it gives me an error saying that the box "should be a descendant of reference view in UIDynamicAnimator". I've included the code for this particular section below.

I've searched for hours and can't figure out why this is happening. Can I completely refresh the view controller so that it works the same way as it does the first time? Should I change my referenceview parameter in UIDynamicAnimator? I'm at a loss. Someone please help!!

_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_gravity = [[UIGravityBehavior alloc] initWithItems:@[box]];
[_animator addBehavior:_gravity];

(I should mention the above code is in an IBAction, but I have also tried adding it in viewDidLoad and that didn't help either....)

Also, the official error that I'm getting is

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'View item (UIImageView: 0x7ffb11d9efd0; frame = (75 40; 70 70); hidden = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = CALayer: 0x7ffb11d9faa0) should be a descendant of reference view in UIDynamicAnimator: 0x7ffb11da8120 (0.000000s) in UIView: 0x7ffb11da84c0 {{0, 0}, {375, 667}}

Here is all the code that has to do with initializing "box":

-(void)viewDidLoad {
box = [[UIView alloc] initWithFrame:CGRectMake(75, 40, 70, 70)];
box.backgroundColor = [UIColor blackColor];
}
-(IBAction)rebounce:(id)sender{
    [self.view addSubview:box];
    box.frame = CGRectMake(75, 40, 70, 70);
    box.hidden = NO;
    _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view ];
    _gravity = [[UIGravityBehavior alloc] initWithItems:@[box]];
    [_animator addBehavior:_gravity];
    [self newBarrierCollision];
    _collision = [[UICollisionBehavior alloc] initWithItems:@[box]];
    _collision.collisionDelegate = self;
    _collision.action =  ^{
    NSLog(@"%@, %@",
          NSStringFromCGAffineTransform(box.transform),
          NSStringFromCGPoint(box.center));
    };
    UIDynamicItemBehavior* itemBehaviour = [[UIDynamicItemBehavior alloc]            initWithItems:@[box]];
    itemBehaviour.elasticity = 0.6;
    [_animator addBehavior:itemBehaviour];
    timer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(CheckIfOffscreen) userInfo:nil repeats:YES];
}    
-(void)CheckIfOffscreen{
    if(box.center.y > SH){
    [timer invalidate];
    [_animator removeAllBehaviors];
    box.frame = CGRectMake(75, 40, 70, 70);
}

Essentially, the box drops, spins downward, and if it falls off the screen, the animation stops and the box is replaced at it's original position at the top until the user hits the button again.

*****EDIT: I have some more information that may be helpful. When I play the game, go back to main menu, and come back again, doing anything to the box programmatically causes the app to crash. I tried adding a tag in ViewDidLoad, and that caused it to crash. It has to be something with the box, but I just can't figure out what.

1
Also, the official error that I'm getting is "terminating with uncaught exception of type NSException" and the reason is "*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'View item (<UIImageView: 0x7ffb11d9efd0; frame = (75 40; 70 70); hidden = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7ffb11d9faa0>>) should be a descendant of reference view in <UIDynamicAnimator: 0x7ffb11da8120> (0.000000s) in <UIView: 0x7ffb11da84c0> {{0, 0}, {375, 667}}'"Annalaissa
You can add an exception breakpoint to check which exact line causes the exception: developer.apple.com/library/ios/recipes/…Michał Ciuba

1 Answers

1
votes

From the error message, I can deduce that this line causes the problem:

_gravity = [[UIGravityBehavior alloc] initWithItems:@[box]];

Each item you use in a UIDynamicBehavior subclass has to be a subview of the reference view, which you passed as a parameter while initalizing UIDynamicAnimator:

_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

So, box has to be a subview of self.view, but it isn't when you go back to the game controller.