use of undeclared identifier in Xcode - objective-c

I'm making an simple game, and Xcode finds a bug says that there is a "use of undeclared identifier 'gameLoop'". How can I fix this?
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
(void)viewDidLoad {
[super viewDidLoad];
gameState = kStateRunning;
[NSTimer scheduledTimerWithTimeInterval: 1.0/60 target:self selector:#selector(gameLoop) userInfo:nil repeats:YES];
rockVelocity = CGPointMake (0, 0);
gravity = CGPointMake (0, kGravity);
- (void)gameLoop {
if (gameState == kStateRunning)
{
[self gameStatePlayNormal];
}
else if (gameState == kStateGameOver)
{
}
}
(void)gameStatePlayNormal {
rockVelocity.y += gravity.y;
rock.center = CGPoint(rock.center.x + ballVelocity.x,rock.center.y + rockVelocity.y);

You need a closing bracket after your viewDidLoad method. Please note that methods in Objective C need a - or + in front of them.
-(void)viewDidLoad {
[super viewDidLoad];
gameState = kStateRunning;
[NSTimer scheduledTimerWithTimeInterval: 1.0/60 target:self selector:#selector(gameLoop) userInfo:nil repeats:YES];
rockVelocity = CGPointMake (0, 0);
gravity = CGPointMake (0, kGravity);
}
- (void)gameLoop {
if (gameState == kStateRunning)
{
[self gameStatePlayNormal];
}
else if (gameState == kStateGameOver)
{
}
}
-(void)gameStatePlayNormal {
rockVelocity.y += gravity.y;
rock.center = CGPoint(rock.center.x + ballVelocity.x,rock.center.y + rockVelocity.y);}

Related

How to fix " Incompatible pointer types sending 'void (void)' to parameter of type 'SEL _Nonnull' " in NSTimer

In Objective C, I am trying to create the method that it's called at the NSTimer selector within the constructor. However, I'm getting this error which causing my app to fail when I build it:
Incompatible pointer types sending 'void (void)' to parameter of type 'SEL _Nonnull'
#implementation Employee
void timerMethod(void);
- (id)init {
self = [super init];
if (self) {
_person = [[Person alloc] init];
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:(timerMethod) userInfo:nil repeats:YES];
}
return self;
}
int counter = 0;
int timeUp = 10;
- (void) timerMethod {
counter += 1;
while (counter != timeUp) {
NSLog(#"A new person has been added");
[_timer invalidate];
counter ++;
}
}
You have to create a #selector
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timerMethod) userInfo:nil repeats:YES];

Change NSTimer interval after a certain number of fires

In the following code, the NSTimer interval is set at 1 second between each picture. My goal is to change the interval after the first two pictures, hello.png and bye.png, to 4 seconds.
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *imageNames = #[#"hello.png",#"bye.png",#"helloagain.png",#"bye again"];
self.images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[self.images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
self.animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 90)];
self.animationImageView.image = self.images[0];
[self.view addSubview:self.animationImageView];
self.animationImageView.userInteractionEnabled = TRUE;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
-(void)changeImage:(NSTimer *) timer {
if (counter == self.images.count - 1 ) {
counter = 0;
}else {
counter ++;
}
self.animationImageView.image = self.images[counter];
}
my goal is to change the interval
You cannot change a timer in any way. To change the firing interval, invalidate and destroy the timer and make a new timer with the new interval.
To do that, you will need to have kept a reference to the timer, as a property of your view controller (something that you have fatally failed to do in your implementation - you would have had no way to stop the timer, and you would have crashed if your view controller ever went out of existence, or else your view controller would have leaked because the timer retains it).
Make the timer object a member variable. Initially set animation time as 1 second. In the callback invalidate the timer and create a new one with 1 or 4 seconds depending on the counter.
#interface ViewController ()
#property (strong,nonatomic) NSMutableArray *images;
#property (strong,nonatomic) UIImageView *animationImageView;
{
NSTimer *_timer;
}
#end
#implementation ViewController {
NSInteger counter;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *imageNames = #[#"hello.png",#"bye.png",#"helloagain.png",#"bye again"];
self.images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[self.images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
self.animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 90)];
self.animationImageView.image = self.images[0];
[self.view addSubview:self.animationImageView];
self.animationImageView.userInteractionEnabled = TRUE;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(bannerTapped:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self.animationImageView addGestureRecognizer:singleTap];
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
-(void)changeImage:(NSTimer *) timer {
[_timer invalidate];
if (counter == self.images.count - 1 ) {
counter = 0;
}else {
counter ++;
}
if(counter == 0 || counter == 1)
{
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
else if(counter == 2 || counter == 3)
{
_timer = [NSTimer scheduledTimerWithTimeInterval:4 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
self.animationImageView.image = self.images[counter];
}
The best/simpliest way :
-(void)Timer{
// Do what you want here
// modify the frequency value if you want.
[NSTimer scheduledTimerWithTimeInterval:frequence target:self selector:#selector(Timer) userInfo:nil repeats:NO];
}
Frequence is a variable that contains the interval.
You just need to call Timer method by yourself the first time ;)
For you, it would give
-(void)changeImage{
if (counter == self.images.count - 1 )
counter = 0;
else
counter ++;
frequence = (counter < 2)?1:4;
self.animationImageView.image = self.images[counter];
[NSTimer scheduledTimerWithTimeInterval:frequence target:self selector:#selector(changeImage) userInfo:nil repeats:NO];
}

Duplicate declaration of method viewDidAppear and startTimerMethod

i am trying to use this code multiple times for different view controllers however i keep on getting the same error .Duplicate declaration of method viewDidAppear and Duplicate declaration of method startTimerMethod . Can you please tell me how to fix this ASAP . thank you in advance .
the code is here
- (void)viewDidAppear:(BOOL)animated {
[self startTimerMethod];
}
- (void) startTimerMethod {
transitionTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(transitionView) userInfo:nil repeats:NO];
}
- (void) transitionView {
[self performSegueWithIdentifier:#"viewTransition" sender:self];
}
- (void)viewDidAppear:(BOOL)animated {
[self startTimerMethod];
}
- (void) startTimerMethod {
transitionTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(transitionView2) userInfo:nil repeats:NO];
}
- (void) transitionView2 {
[self performSegueWithIdentifier:#"viewTransition2" sender:self];
}
Just delete these below three method one time which you have declared two times-
- (void) startTimerMethod {
transitionTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(transitionView) userInfo:nil repeats:NO];
}
- (void) transitionView {
[self performSegueWithIdentifier:#"viewTransition" sender:self];
}
- (void)viewDidAppear:(BOOL)animated {
[self startTimerMethod];
}

Change array of images with NSTimer

I want to implement a auto change image gallery. here is my code in the controller. i have a uiimageview named image. i want to link the array of image to my image view to let it auto change after a few seconds. What should i do??
- (void)viewDidLoad{
[super viewDidLoad];
[self performSelector:#selector(changeImage) withObject:nil afterDelay:2];
}
-(void)changeImage {
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"animated-fish-1.jpg"], [UIImage imageNamed:#"tumblr_7"], [UIImage imageNamed:#"th_nature_4.jpg"],nil];
image.animationImages = images;
// how to let the array of image load and link to the perform selector??
// what should i continue from here?
}
Store the images in an ivar
#interface YourClass : SomeSuperClass
#property (nonatomic, strong) NSArray *images;
#end
Don't start the timer in viewDidLoad as the view will not be on the screen yet so there is no point - move it to viewDidAppear:
- (void)viewDidLoad
{
[super viewDidLoad];
self.images = #[ ... ]; // or pass these into the class
self.imageView.image = self.images[0];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:#selector(changeImage:)
userInfo:nil
repeats:YES];
}
-(void)changeImage:(NSTimer *)timer
{
NSInteger currentIndex = [self.images indexOfObject:self.imageView.image];
NSInteger nextIndex = (currentIndex + 1) % self.images.count;
self.imageView.image = self.images[nextIndex];
// If for any reason you need to cancel the image rotation
if ([self shouldCancelImageRotation]) {
[timer invalidate];
}
}
To animate the images using timer, try this
- (void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(animateImages)
userInfo:nil
repeats:YES];
imageCount = 1;
}
-(void)animateImages
{
imageCount = imageCount + 1;
NSString *imageName = [NSString stringWithFormat:#"image%i.png"];
[theImage setImage:[UIImage imageNamed:imageName]];
}
You should use NSTimer, per example, you can use this method :
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html#//apple_ref/occ/clm/NSTimer/scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
This method allow you to define a selector to use and repeats every x seconds
try like this ,
take one global varaible index
- (void)viewDidLoad{
[super viewDidLoad];
index=0;
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"animated-fish-1.jpg"], [UIImage imageNamed:#"tumblr_7"], [UIImage imageNamed:#"th_nature_4.jpg"],nil];
imageview.image = [images objectAtIndex:index];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(changeImage) userInfo:nil repeats:YES];
}
-(void)changeImage {
index++;
if(index==[images count]){
index=0;
}
imageview.image = [images objectAtIndex:index];
}

How can I produce a blinking label

I want a label to be shown for 0.4 seconds and then hidden for 0.8 seconds - in an infinite loop.
How can I pull that off?
NSTimer and UIViews hidden property would be one possibility
I would say to use NSTimer. You could do it the following way:
Say your label is myLabel:
#property (weak, nonatomic) IBOutlet UILabel *myLabel;
You should create a method to be called by NSTimer:
- (void)changeLabelState:(NSTimer *)timer
{
if(self.myLabel.hidden == TRUE)
{
self.myLabel.hidden = FALSE; //change comparassion to assing
[NSTimer scheduledTimerWithTimeInterval:0.4
target:self
selector:#selector(changeLabelState:)
userInfo:nil
repeats:NO];
}
else
{
self.myLabel.hidden = TRUE;
[NSTimer scheduledTimerWithTimeInterval:0.8
target:self
selector:#selector(changeLabelState:)
userInfo:nil
repeats:NO];
}
}
And initialize NSTimer somewhere like so:
[NSTimer scheduledTimerWithTimeInterval:0.4
target:self
selector:#selector(changeLabelState:)
userInfo:nil
repeats:NO];
Note that you could also do the following:
[self performSelector:#selector(changeLabelState:) withObject:nil afterDelay:0.4];
- (void)changeLabelState:(NSTimer *)timer
{
if(self.myLabel.hidden == TRUE)
{
self.myLabel.hidden = FALSE;
[self performSelector:#selector(changeLabelState:) withObject:nil afterDelay:0.4];
}
else
{
self.myLabel.hidden = TRUE;
[self performSelector:#selector(changeLabelState:) withObject:nil afterDelay:0.8];
}
}
Something Like the below.
In viewDidLoad:
NSTimer *silly = [NSTimer timerWithTimeInterval:0.4 target:self selector:#selector(question) userInfo:nil repeats:YES];
Function
-(void)question {
if(label.isHidden){
label.hidden = false;
} else {
label.hidden = true;
}
}
Make sure you have a UILabel defined in scope of this function and it should work. UNTESTED.