1

I have 5 UIImageViews getting animated down the screen. If one is pressed, and it meets the requirements, it will add 1 to your score, using this:

self.score.text = @(self.score.text.integerValue + 1).stringValue;

But when the text in the UILabel updates, all the animations stop abruptly and the remaining UIImageViews disappear. But, the animation only restarts after a few seconds, as if the images are becoming hidden. The code to animate the images and change image(They are the same for each one):

- (void) squareOneMover {
    NSUInteger r = arc4random_uniform(3);
    [self.squareOne setHidden:NO];
    CGPoint originalPosition = self.squareOne.center;
    CGPoint position = self.squareOne.center;
    originalPosition.y = -55;
    position.y += 790;
    [self.squareOne setCenter:originalPosition];

    [UIView animateWithDuration:r + 3
                          delay:0.0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         [self.squareOne setCenter:position];
                     }
                     completion:^(BOOL complete) {
                         if (complete) {
                             [self squareOneColour];
                             [self squareOneMover];
                         }
                     }
    ];
}

- (void) squareOneColour {
    NSUInteger r = arc4random_uniform(5);
    [self.squareOne setImage:[self.colorArray objectAtIndex:r]];
}

Anyone have a solution? And if by changing the text in a UILabel is supposed to stop animations (I don't know why they would do so) can someone provide a workaround to make keeping score possible.

Edit: I created a button that would increase the integer value of score. This means I can change the text in the UILabel manually. The animations still stopped the moment the text changed.

Edit 2: Method for the pressed event:

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

    NSUInteger a = [self.colorArray indexOfObject:self.squareOne.image];
    NSUInteger b = [self.iconColorArray indexOfObject:self.icon.image];
    if ([self.squareOne.layer.presentationLayer hitTest:touchLocation]) {
        _squareOne.hidden = YES;
    }
    if (a!=b) {
        if (self.squareOne.hidden==YES) {
            NSLog(@"NO");
            }
        }
    if (a==b) {
        if ([self.squareOne.layer.presentationLayer hitTest:touchLocation]) {
            self.score.text = @(self.score.text.integerValue + 1).stringValue;
        }
    }

    if ([self.squareTwo.layer.presentationLayer hitTest:touchLocation]) {
        _squareTwo.hidden = YES;
    }
}

Looking at Matt's answer, how would I animate the UIImageView by "changing its constraints"?

Constraints:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-25-[btn1]-25-[btn2(==btn1)]-25-[btn3(==btn1)]-25-[btn4(==btn1)]-25-[btn5(==btn1)]-25-|" options:0 metrics:nil views:views]];

[self.view addConstraint:[NSLayoutConstraint 
      constraintWithItem:self.squareOne 
               attribute:NSLayoutAttributeTop 
               relatedBy:NSLayoutRelationEqual 
                  toItem:self.view 
               attribute:NSLayoutAttributeTop 
              multiplier:0.0 
                constant:-55.0]];
Minestrone-Soup
  • 399
  • 1
  • 16

3 Answers3

1

The problem is this line:

 [self.squareOne setCenter:position];

You are animating the position of squareOne by setting its position. But meanwhile you also have constraints that also position squareOne. That fact remains concealed until you change the text of the label; that triggers layout, and now the constraints all assert themselves, putting an end to everything else that was going on.

One solution is to animate the position of squareOne by changing its constraints. Now when layout is triggered, the existing constraints will match the situation because they are the only force that is positioning things.

matt
  • 515,959
  • 87
  • 875
  • 1,141
0
 //what all are you checking with the if's? 

 //I'm just curious there's a lot going on here

**//if this evaluates true
if ([self.squareOne.layer.presentationLayer hitTest:touchLocation]) {
    _squareOne.hidden = YES;
}**
if (a!=b) {
    if (self.squareOne.hidden==YES) {
        NSLog(@"NO");
        }
    }
if (a==b) {
    **          //this will evaluate true also
    if ([self.squareOne.layer.presentationLayer hitTest:touchLocation]) {
        self.score.text = @(self.score.text.integerValue + 1).stringValue;
    }**
}

//this works fine even when I added everything from interface builder which almost never happens

Update

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic)UILabel *label;
@property int tapCount;
@end

@implementation ViewController


-(void)viewDidLoad{

     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]init];
    [tap addTarget:self action:@selector(userTap:)];
    [self.view addGestureRecognizer:tap];


}
-(UILabel*)label{

    if (!_label) {
        _label = [[UILabel alloc]init];
        _label.text = @"taps:%3i",0;
        [_label sizeToFit];
        _label.center = self.view.center;
        [self.view addSubview:_label];
    }

    return _label;
}

-(void)userTap:(UITapGestureRecognizer*)sender {
    NSLog(@"tap");
 self.tapCount ++;
    [UIView animateWithDuration:1
                     animations:^{
                        self.label.text = [NSString stringWithFormat:@"taps:%i",self.tapCount];
                        self.label.center = [sender locationInView:self.view];

                    }
                     completion:nil];

}



@end

**just cleaning up the code a bit for future onlookers ** direct copy and paste only delete everything inside ViewController.m on a new project and paste this in it's place

admdrew
  • 3,790
  • 4
  • 27
  • 39
  • Don't worry about the if statements. I like Matt's answer, so I want to know how to animate by changing constraints. Not sure what your answer is for though – Minestrone-Soup Nov 21 '14 at 14:06
  • well you said you don't want the label hidden and you said the score is on the label , but the only way the label will get updates is if the square is hidden which (contains the label?) –  Nov 21 '14 at 20:34
  • if you really want to quit frustrating yourself you should start with what you know works and then move forwards. You know that your touch event is received; if it were me I'd comment out the if statements and start with updating the text without them and then move forward. The above code is a direct copy and paste from a tiny program I just wrote, it works flawlessly and nothing disappears or constrains to objects that from previous constraints. –  Nov 21 '14 at 22:39
0

Instead of animating the constraints by hand, you can also have UIImageView generate constraints during animation (which does not get broken by a sibling UILabel). Like in this question.

Community
  • 1
  • 1
Jokester
  • 5,501
  • 3
  • 31
  • 39