Reputation:
I am a newbie in objective-c and having trouble with NSTimer. While learning objective-c by developing games, I tried to move sprite using left and right button with the help of NSTimer. But, as it seems the selector is not being called. I searched stack overflow and found some solutions, but any solutions I've seen, not working. Here is my code-
#import "GameViewController.h"
@interface GameViewController ()
@property (strong) UIImage *playerImage;
@property (strong) UIImageView *playerView;
@property (strong) NSTimer *moveTimer;
@property CGRect playerRect;
@property int count;
@end
@implementation GameViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.count=0;
self.playerImage = [UIImage imageNamed:@"ship.png"];
self.playerView = [[UIImageView alloc] initWithImage: self.
playerImage];
self.playerRect = CGRectMake(50,400, 32,32);
self.playerView.frame = self.playerRect;
[self.view addSubview: self.playerView];
// this timer calls selector
// self.moveTimer = [NSTimer scheduledTimerWithTimeInterval:.03
// target:self
// selector:@selector(movePlayerRight:)
// userInfo:nil
// repeats:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)moveLeft:(id)sender {
[self releaseTouch];
NSLog(@"Left Move");
//this timer does not call selector
self.moveTimer = [NSTimer scheduledTimerWithTimeInterval:.03
target:self
selector:@selector(movePlayerLeft:)
userInfo:nil
repeats:YES];
// [[NSRunLoop mainRunLoop] addTimer:self.moveTimer forMode:NSDefaultRunLoopMode];
// [[NSRunLoop mainRunLoop] run];
//[self.moveTimer fire];
}
- (IBAction)moveRight:(id)sender {
[self releaseTouch];
NSLog(@"Right Move");
// if(![NSThread isMainThread])
// dispatch_async(dispatch_get_main_queue(), ^{
//this timer does not call selector
self.moveTimer = [NSTimer scheduledTimerWithTimeInterval:.03
target:self
selector:@selector(movePlayerRight:)
userInfo:nil
repeats:YES];
}
- (IBAction)TouchRelease:(id)sender {
[self releaseTouch];
}
-(void) movePlayerRight:(NSTimer*)timer {
NSLog(@"Right Move Selector");
if(self.playerRect.origin.x <= 320){
self.playerRect = CGRectOffset(self.playerRect, 3, 0);
self.playerView.frame = self.playerRect;
}
}
-(void) movePlayerLeft:(NSTimer*)timer {
NSLog(@"Left Move Selector");
if(self.playerRect.origin.x >= 10){
self.playerRect = CGRectOffset(self.playerRect, -3, 0);
self.playerView.frame = self.playerRect;
}
}
-(void)releaseTouch{
if(self.moveTimer != nil){
[self.moveTimer invalidate];
self.moveTimer = nil;
}
}
@end
Let me explain what I've tried.
Then, in a solution, I found that, thread might be creating problem; So, I tried-
if(![NSThread isMainThread])
dispatch_async(dispatch_get_main_queue(), ^{
But, this is not the case with the thread, as the debugger does not step in the "dispatch_async" line.
What am I doing wrong?
**Solution: ** As suggested by @Danil Valeev and @aman.sood unchecked the Storyboard auto-layout, changed the property to 'nonatomic'; and now selector is being called from timer :)
Upvotes: 0
Views: 511
Reputation: 874
Replace [NSRunLoop mainRunLoop] with [NSRunLoop currentRunLoop] it should work
Upvotes: 0
Reputation: 211
Check that movePlayerRight: or movePlayerLeft: are called. And that Auto Layout is not using in the view (I think it is the reason). You can disable Auto Layout in the xib/storyboard file in the first tab of Utilities.
Upvotes: 2