0

I have a UIView animateWithDuration (in a method being called by a button) that animates a UIImageViews. The important code before the animation code: (the title is appropriate, just keep reading)

//Sets _squareOneNumber to 0 (this is going to be the changing value)
_squareOneNumber = 0;

Basically the animation code just allows user interaction and animates the image to down the screen at a random pace.

But, it's the completion block that is killing me (don't worry about a and b):

if (self.squareOneNumber==0) {
    if (a==b) {
        [self gameOverImagePutter];
        NSLog(@"One wasn't pressed");
    }
}

The value of _squareOneNumber changes to 1 if it is pressed.

//In touchesBegan method
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];

if ([self.squareOne.layer.presentationLayer hitTest:touchLocation]) {
    [_squareOne setHidden:YES];
    _squareOneNumber = 1;
}

The completion block should call gameOverImagePutter if squareOne wasn't pressed (squareOneNumber=0) and a==b. But it is always called when squareOne is pressed (squareOneNumber=1). To me, the code should work fine. But I think the issue is that squareOneNumber isn't getting updated even though its value has changed.

So basically this is my question:

  • how to I get the code to work?
  • why isn't squareOneNumber realizing it's value has changed?
Minestrone-Soup
  • 399
  • 1
  • 16
  • Please provide more code, how you are using "squareOneNumber" inside blocks. If yes, consider prefixing "__block" to "squareOneNumber", so that block can see the changes. – gagarwal Nov 27 '14 at 00:07
  • @gagarwal I have included all the code the includes `squareOneNumber` besides the `@property` in the head file. What other code do you need? I have included everything relevant. – Minestrone-Soup Nov 27 '14 at 00:20
  • Where is _squareOneNumber = 0; is being called in? You have a button that you press and it moves the views and then you have a tap gesture method also? – Yan Nov 27 '14 at 00:36
  • It's being called before the animation code like I said. And Yes @Yan – Minestrone-Soup Nov 27 '14 at 00:45
  • Forget about the second comment. The way the app works, user presses on squareone and touchesBegan method is called setting _squareOneNumber=1 but when is the animation called? – Yan Nov 27 '14 at 00:53
  • When a button is pressed, the method that has the animation code, is called. – Minestrone-Soup Nov 27 '14 at 00:55
  • Do NSLog next to _squareOneNumber = 1; i think it's being called numerous times before the animation ends and resets _squareOneNumber to 1 – Yan Nov 27 '14 at 00:57
  • Do you mean it resets to 0? And I tried it and it is only being called once @Yan – Minestrone-Soup Nov 27 '14 at 00:59
  • Is it the issue that gameOverImagePutter is not being called because squareOneNumber = 1 ? – Yan Nov 27 '14 at 01:03
  • @Yan No the issue is that it is being called. When `squareOne` is pressed nothing should be called. – Minestrone-Soup Nov 27 '14 at 01:04
  • Sorry still trying to understand the flow of the app. So when you press it you set the _squareOneNumber to 1 and then reset it to 0 before the animation – Yan Nov 27 '14 at 01:06
  • @Yan That is correct – Minestrone-Soup Nov 27 '14 at 01:07
  • So then in the completion block self.squareOneNumber is always going to be 0 because you set it before the animation starts – Yan Nov 27 '14 at 01:09
  • @Yan Why is that. Not always. It may equal 1 if `squareOne` is pressed. – Minestrone-Soup Nov 27 '14 at 01:10
  • You said that animation is called right after you press a button and right before the animation starts u set squareOneNumber to 0 – Yan Nov 27 '14 at 01:17
  • I guess you are pressing the button again before the animation completes so you expect that squareOneNumber would be set to 1 at that time in the completion block and its not – Yan Nov 27 '14 at 01:20
  • I guess your question is if the value updates inside a block / completion block if changed in a different thread – Yan Nov 27 '14 at 01:22
  • @Yan Thanks. I'll change title. Have a solution though? – Minestrone-Soup Nov 27 '14 at 01:24
  • I think you should do NSLog after _squareOneNumber = 1; and before if (self.squareOneNumber==0) to see when it changes – Yan Nov 27 '14 at 01:32
  • @Yan This makes it even weirder: in the debugger it did say `squareOneNumber=1` happened before the if-statement. So is the if-statement just being ignored? – Minestrone-Soup Nov 27 '14 at 01:36
  • its equals to one and still goes inside the if statement? – Yan Nov 27 '14 at 01:40
  • @Yan Yup. It is about 2-3 seconds after when the if-statement takes place, and `squareOneNumber` is still considered 0 – Minestrone-Soup Nov 27 '14 at 01:45
  • I think because you running the completion on different thread you don't really have any control when it is called. That is why you can't really control if the squareOneNumber is 1 or 0 at that time. I think you have to rethink the logic a little – Yan Nov 27 '14 at 01:47
  • The problem is that you are able to press before first animation completes. You have to handle this type of situation either in the completion block or before. – Yan Nov 27 '14 at 02:17
  • @Yan How would I do this? Btw comments is getting crowded. Mind righting an answer? – Minestrone-Soup Nov 27 '14 at 02:27
  • I know but not sure what to put as answer because there is no answer yet :) Don't you want to end the animation when you press again? – Yan Nov 27 '14 at 02:44
  • @Yan Yes, as long as `a==b` – Minestrone-Soup Nov 27 '14 at 12:52

1 Answers1

0

i recreated the code that i think you have from what you posted and it does work as expected. squareOneNumber is updated when completion block executes. The image is on screen, when the button is pressed image starts moving. When you press on the image it is hidden and squareOneNumber is set to 1. Then in few seconds completion block is being executed with the update value.

The only way that won't work if you press the button again and the animation is running with the hidden image and squareOneNumber resets to 0 which will be reflected in the completion block. Here is my code. Let me know if i correctly recreated your part of the code.

#import "ViewController.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *squareOne;
@property (nonatomic) NSUInteger squareOneNumber;
@end

@implementation ViewController
- (IBAction)animateImage:(id)sender
{
    [UIView animateWithDuration:4.0 animations:^{
        self.squareOneNumber = 0;
        self.squareOne.center = CGPointMake(300, 300);

    } completion:^(BOOL finished) {
        NSLog(@"square one in completion %lu",self.squareOneNumber);
        if (self.squareOneNumber == 0) {
            NSLog(@"0");
        }else{
            NSLog(@"1");
        }

    }];

}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    if ([self.squareOne.layer.presentationLayer hitTest:touchLocation]) {
        [self.squareOne setHidden:YES];
        self.squareOneNumber = 1;
        NSLog(@"square one in touches began %lu",self.squareOneNumber);
    }
}

@end

Here is the NSLog output when imageView is pressed

2014-11-30 23:14:30.541 StackOveflowAnimation[3885:1092103] square one in touches began 1
2014-11-30 23:14:33.356 StackOveflowAnimation[3885:1092103] square one in completion 1
2014-11-30 23:14:33.356 StackOveflowAnimation[3885:1092103] 1
Yan
  • 3,533
  • 4
  • 24
  • 45