Xcoder
Xcoder

Reputation: 199

Strange behaviour of UIImageView and UILabel using NSTimer and animations

It is a really odd situation and I have never had a problem like this, and I would really appreciate any help that I get on this post. I have made a simple game. I will give .h and .m below.

Game30s.h :

//
//  Game30s.h
//  Speedy
//
//  Created by Ajay Venkat on 15/10/2014.
//  Copyright (c) 2014 AJTech. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface Game30s : UIViewController {
    IBOutlet UILabel *scorelabel;
    IBOutlet UIButton *bar1;
    IBOutlet UIButton *bar2;
    BOOL isCracked;
    BOOL isCracked2;
    NSTimer *go;
    NSTimer *collision;
    IBOutlet UIImageView *wall;
    IBOutlet UIButton *start;
    IBOutlet UIButton *contin;
    NSTimer *time;
    NSTimer *timestart;
    int timem;
    IBOutlet UILabel *timemanage;
    int score;
}

-(void)tensecs;
-(void)timetwo;
-(void)goRight;
-(void)col;
-(IBAction)Statt;
-(IBAction)Tap1;
-(IBAction)Tap2;

@property (nonatomic) BOOL gameCenterEnabled;
@property (nonatomic, strong) NSString *leaderboardIdentifier;

@end

Game30s.m :

//
//  Game30s.m
//  Speedy
//
//  Created by Ajay Venkat on 15/10/2014.
//  Copyright (c) 2014 AJTech. All rights reserved.
//

#import "Game30s.h"
@import GameKit;

@interface Game30s()
@end

@implementation Game30s {
    int cracknum;
    float speed;
    int score2;
    int totscore;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    timestart = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timetwo) userInfo:nil repeats:YES];
    contin.hidden = YES;
    start.hidden = NO;
    bar1.hidden = YES;
    bar2.hidden = YES;
    [self authenticateLocalPlayer];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

-(IBAction)Tap1 {
    int w = ([[UIScreen mainScreen] bounds].size.width);
    int h = ([[UIScreen mainScreen] bounds].size.height);
    w = w / 2;
    int r1x = (arc4random() %240) + w ;
    int r1y = (arc4random() %h);
    bar1.center = CGPointMake(r1x, r1y);
    speed = speed + 0.5;
    score = score + 1; 
}

-(IBAction)Tap2 {
    int w = ([[UIScreen mainScreen] bounds].size.width);
    int h = ([[UIScreen mainScreen] bounds].size.height);
    w = w / 2;
    int r2x = (arc4random() %240) + w ;
    int r2y = (arc4random() %h);
    speed = speed + 0.7;
    bar2.center = CGPointMake(r2x, r2y);
    score = score + 1;
}

-(void)goRight {
    bar1.center = CGPointMake(bar1.center.x - speed, bar1.center.y);
    bar2.center = CGPointMake(bar2.center.x - speed, bar2.center.y);   
}

-(void)tensecs {
    if (timem > 0) {
        timem = timem - 1;
        NSString* myString = [@(timem) stringValue];
        timemanage.text = myString;
    } else if (timem == 0) {
        [timestart invalidate];
        NSString* myString = [@(score) stringValue];
        scorelabel.text = myString;
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setInteger:score forKey:@"thirtysecond"];
        bar1.hidden = YES;
        bar2.hidden = YES;
        start.hidden = NO;
        start.enabled = YES;
        contin.hidden = NO;
        contin.enabled = YES;
        [go invalidate];
        [time invalidate];
    }
}

-(void)col {
    if (CGRectIntersectsRect(bar1.frame, wall.frame)) {
        int r2x = (arc4random() %300) + 300 ;
        int r2y = (arc4random() %375);
        bar2.center = CGPointMake(r2x, r2y);
        int r1x = (arc4random() %300) + 300 ;
        int r1y = (arc4random() %375);
        bar1.center = CGPointMake(r1x, r1y);
    }

    if (CGRectIntersectsRect(bar2.frame, wall.frame)) {
        int r2x = (arc4random() %300) + 300 ;
        int r2y = (arc4random() %375);
        bar2.center = CGPointMake(r2x, r2y);
        int r1x = (arc4random() %300) + 300 ;
        int r1y = (arc4random() %375);
        bar1.center = CGPointMake(r1x, r1y); 
    }
}

-(IBAction)Statt {
    timem = 30;
    score = 0;
    contin.hidden = YES;
    contin.enabled = NO;
    time = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tensecs) userInfo:nil repeats:YES];
    bar1.hidden = NO;
    bar2.hidden = NO;
    int r2x = (arc4random() %300) + 300 ;
    int r2y = (arc4random() %375);
    bar2.center = CGPointMake(r2x, r2y);
    int r1x = (arc4random() %300) + 300 ;
    int r1y = (arc4random() %375);
    bar1.center = CGPointMake(r1x, r1y);
    cracknum = 0;
    go = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(goRight) userInfo:nil repeats:YES];
    collision = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(col) userInfo:nil repeats:YES];
    speed = 3;
    start.hidden = YES;
    start.enabled = NO;
}

-(void)authenticateLocalPlayer{
    // Instantiate a GKLocalPlayer object to use for authenticating a player.
    GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
    localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
        if (viewController != nil) {
            // If it's needed display the login view controller.
            [self presentViewController:viewController animated:YES completion:nil];
        } else {
            if ([GKLocalPlayer localPlayer].authenticated) {
                // If the player is already authenticated then indicate that the Game Center features can be used.
                _gameCenterEnabled = YES;
                // Get the default leaderboard identifier.
                [[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {
                    if (error != nil) {
                        NSLog(@"%@", [error localizedDescription]);
                    } else{
                        _leaderboardIdentifier = @"thirtysecondtappers";
                    }
                }];
            } else {
                _gameCenterEnabled = NO;
            }
        }
    };
}

@end

So this is the code. In the method -(void)tensecs I have said:

NSString* myString = [@(timem) stringValue];
timemanage.text = myString;

And I linked up everything properly! Then what happens in the simulator or on any device is that the time label counts down properly from 30 down to 0. But every time a number goes down for example 29 to 28 the UIImageViews reset to their home location on the screen.

See I show screen shots here.

The Image moves 1cm and comes back.

Then again

I tried deleting that code

NSString* myString = [@(timem) stringValue];
timemanage.text = myString;

and then it did not do this anymore. I don't know why this is happening!

Summary:

The UIImageView is going back to its home location when the timer changes a number on label! Also I have added constraints to the image on the actual designer. Is this why?

Upvotes: 0

Views: 57

Answers (1)

rdelmar
rdelmar

Reputation: 104082

This is because of auto layout. If you haven't turned off auto layout, and move views by setting their frames, then when the view needs to redraw (like when your score label changes), the view you moved will revert to the position defined by its constraints. To fix this, you either need to reposition your view by adjusting the constraints, or turn off auto layout.

Upvotes: 1

Related Questions