Reset button on NSTimer - ios

I have an NSTimer and I need a reset button that resets the variable on screen and stops that timer until it is started agin by the start button. Here's some code:
#implementation TimeController
int timeTick = 0;
NSTimer *timer;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
labelTime.text = #"0";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)startTimer:(id)sender {
[timer invalidate];
timer= [NSTimer scheduledTimerWithTimeInterval:60.0 target:(self) selector:(#selector(tick)) userInfo:(nil) repeats:(YES)];
}
- (IBAction)resetTicktock:(id)sender {
[timer invalidate];
}
-(void)tick{
timeTick++;
NSString *timeString = [[NSString alloc] initWithFormat:#"%d", timeTick];
labelTime.text = timeString;
}
#end
Thanks in advance!

It looks like you have a function started already to stop the timer. Just reset the variable there.
- (IBAction)resetTicktock:(id)sender {
[timer invalidate];
labelTime.text = #"0";
}
Link your button to this method in your storyboard for the action "Touch Up Inside".

You need reset the timeTick and the the text of label
- (IBAction)resetTicktock:(id)sender {
[timer invalidate];
labelTime.text = #"0";
timeTick = 0;
}

Related

How to have two buttons change title and do two different functions?

I'm using Objective-C to make a stopwatch. I already have a basic stop watch with 3 buttons: Start, Stop and reset. Here is my code for viewcontroller.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)Start:(id)start
{
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}
-(IBAction)Stop:(id)sender
{
[Timer invalidate];
}
-(IBAction)Restart:(id)sender
{
[Timer invalidate];
addingtheTime = 0;
Label.text = [NSString stringWithFormat:#"0.00"];
}
-(void)addingthetime
{
addingtheTime = addingtheTime + 0.01;
Label.text = [NSString stringWithFormat:#"%.2f", addingtheTime];
}
#end
And here is my code for viewcontroller.h:
#import <UIKit/UIKit.h>
float addingtheTime;
#interface ViewController : UIViewController
{
IBOutlet UILabel *Label;
NSTimer *Timer;
}
#end
So my question is how do I make the Start button do the following once clicked:
Start the timer
Change the title to stop
(Click the same button again)
Stop the timer
Change the title to start
So the aim is to have only one button which starts and stops the timer but please I want the title to change as well.
Don't worry about the reset button as I want that to remain by itself.
PS. Please explain things clearly because I find it really hard to understand some things and I am a beginner so try and keep it fairly simple thanks, and sorry if the question isn't clear.
You can use button.tag property to achieve this. By Default the button.tag property have 0. So assume that 0 is a state when timer is Not started and 1 is the state when timer is started. You can manipulate .tag property according to your custom logic.
-(IBAction)Start:(id)start
{
UIButton *button = (UIButton *)start;
if (button.tag == 0){
button.tag = 1;
[button setTitle:#"Stop" forControlState:UIControlStateNormal];
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}else {
button.tag = 0;
[button setTitle:#"Stop" forControlState:UIControlStateNormal];
//Invoke your method to stop Timer.
}
}
In the ViewController.h:
#import <UIKit/UIKit.h>
float addingtheTime;
#interface ViewController : UIViewController
{
IBOutlet UILabel *Label;
NSTimer *Timer;
}
#end
In the ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)addingthetime
{
addingtheTime = addingtheTime + 0.01;
Label.text = [NSString stringWithFormat:#"%.2f", addingtheTime];
}
- (IBAction)startOrStopAction:(UIButton *)sender {
// stop
if ([sender.titleLabel.text isEqualToString:#"stop"]) {
[Timer setFireDate:[NSDate distantFuture]];
[sender setTitle:#"start" forState:UIControlStateNormal];
}
// start
else {
if (!Timer) {
Timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(addingthetime) userInfo:nil repeats:YES];
}else {
[Timer setFireDate:[NSDate date]];
}
[sender setTitle:#"stop" forState:UIControlStateNormal];
}
}
#end
The result:
In iPhone:
In iPad:

Method being called constantly until the view is dismissed

I have an endGame view that loads when the user completes a game. It is presented modally over top of the game view. In viewDidLoad I am calling a method to save data such the score and how many of a certain game mode they have played. That method is being called multiple times - about once per second, but it is irregular.
End Game Screen:
#import "endGameScreen.h"
#import "ViewController.h"
#import "GameData.h"
#implementation endGameScreen
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)awakeFromNib {
[self getAchievementData];
}
- (void)getAchievementData {
[RWGameData sharedGameData].timedPlayed++;
NSLog(#"Timed played: %ld", [RWGameData sharedGameData].timedPlayed);
}
- (void)writeAchievementforKey:(NSString *)achKey {
[data setObject:[NSNumber numberWithInteger:1] forKey:achKey];
[data writeToFile: path atomically:YES];
}
I am loading the endGameScreen class like this:
GameViewController.m
- (void)viewDidLoad {
if (self.gameMode == 1) {
self.gridSize = 3;
secondsLeft = 10;
[self countdownTimer];
}
}
-(void)countdownTimer {
secondsLeft = minutes = seconds = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
}
// Timer in the game going to zero
- (void)updateCounter:(NSTimer *)theTimer {
if (secondsLeft > 0 ){
secondsLeft -- ;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft %3600) % 60;
timePlayedLabel.text = [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
if (secondsLeft == 1) {
//Call endGame method
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(endGame)
userInfo:nil
repeats:NO];
}
}
else {
secondsLeft = 10;
}
}
- (void)endGame {
[timer invalidate];
[self saveScores];
//Segue in the storyboard
[self performSegueWithIdentifier:#"endGame" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"endGame"]) {
endGameScreen *vc = [segue destinationViewController];
if (self.gameMode == 1) {
vc.gameMode = 1;
}
else {
vc.gameMode = 2;
}
}
}
I am getting NSLog messages that continually increment saying "Mode One played: 27", "Mode One played: 28", "Mode One played: 29", and so on.
Your -endGame method isn't invalidating the timer you think it is.
-updateCounter: is overwriting your timer instance variable with the new one-shot timer for calling -endGame, but that doesn't stop the other timer, the one created in -countdownTimer. That timer continues to fire, calling -updateCounter:, which keeps creating more one-shot timers to call -endGame. So, that gets called repeatedly.

Why is one of my NSTimer messing up my background movement?

I have two NSTimer. The problem is that my countdown timer messes up my background positioning as soon as the countdown timer stops. The background moves properly up until the point where the background timer stops. Then it will automatically reposition the background to the starting position, which I do not want because it seems glitchy when it happens. I want it to keep flowing smoothly as soon as the countdown timer stops. If I were to take the countdown timer out, the background movement works perfectly. Here is my code:
PlayViewController.h
#import <UIKit/UIKit.h>
#interface PlayViewController : UIViewController
{
int countdownStatus;
IBOutlet UIImageView *background;
NSTimer *backgroundMovement;
NSTimer *gameCountdownTimer;
}
#property (strong, nonatomic) IBOutlet UILabel *countdownLabel;
- (void)backgroundMoving;
- (void)gameCountdown;
#end
PlayViewController.m
#import "PlayViewController.h"
#interface PlayViewController ()
#end
#implementation PlayViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.countdownLabel.text = #"3";
countdownStatus = 2;
gameCountdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(gameCountdown) userInfo:nil repeats:YES];
backgroundMovement = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:#selector(backgroundMoving) userInfo:nil repeats:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)backgroundMoving
{
background.center = CGPointMake(background.center.x - 1, background.center.y);
CGRect backgroundFrame = background.frame;
if(backgroundFrame.origin.x < -370)
{
CGRect myFrame = background.frame;
myFrame.origin.x = 0;
myFrame.origin.y = 0;
background.frame = myFrame;
}
}
- (void)gameCountdown
{
if(countdownStatus == 2)
self.countdownLabel.text = #"2";
else if(countdownStatus == 1)
self.countdownLabel.text = #"1";
else
self.countdownLabel.text = #"";
countdownStatus--;
}
#end

Automatically start countdown Xcode XIB

I want to create a button that takes me to another view controller and automatically starts a countdown from 3 to 0, but i don't know how to set the countdown on the other view controller. Here's the code i tried:
#implementation TestViewController
-(IBAction)test:(id)sender {
CountdownViewController *cdvc = [[CountdownViewController alloc]
initWithNibName:#"CountViewController" bundle:nil];
[self.navigationController pushViewController:cdvc animated:YES];
}
#implementation CountdownViewController
int maintInt = 3;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
-(void)countDown {
maintInt -= 1;
count.text = [NSString stringWithFormat:#"%i", maintInt];
if(maintInt==1){
[timer invalidate];
}
}
You have to place your countdown code in a method, which you should call in viewDidLoad or viewWillAppear method regarding your needs.
#implementation TestViewController
-(IBAction)test:(id)sender {
CountdownViewController *cdvc = [[CountdownViewController alloc]
initWithNibName:#"CountViewController" bundle:nil];
[self.navigationController pushViewController:cdvc animated:YES];
}
#end
#implementation CountdownViewController
- (void)viewDidLoad {
[super viewDidLoad];
// .. customize your views here ..
// Initialize the timer once your view has been loaded.
//
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countDown:) userInfo:nil repeats:YES];
}
static int maintInt = 3;
- (void)countDown:(NSTimer *)timer {
count.text = [NSString stringWithFormat:#"%i", maintInt];
maintInt -= 1;
if (maintInt == 0 && timer) {
[timer invalidate];
timer = nil;
}
}
#end

Keep getting expression result unused when trying to update UILabel

I'm very new to programming in general. I am trying to update the UILabel "Lives" with the integer life. However I keep getting the warning "expression result unused" in the line
Lives.text = #"",life;
//
// Game.m
// SprinklerDash
#import "Game.h"
#interface Game ()
#end
#implementation Game
-(void)Walk{
Runner.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Runner1.png"],
[UIImage imageNamed:#"Runner2.png"],
[UIImage imageNamed:#"Runner3.png"],
[UIImage imageNamed:#"Runner4.png"],
[UIImage imageNamed:#"Runner5.png"],
[UIImage imageNamed:#"Runner6.png"],
[UIImage imageNamed:#"Runner7.png"],
[UIImage imageNamed:#"Runner8.png"], nil];
[Runner setAnimationRepeatCount:INFINITY];
Runner.animationDuration = .75;
[Runner startAnimating];
}
-(void)Moving{
Runner.center = CGPointMake(Runner.center.x, Runner.center.y - UpMovement);
if(CGRectIntersectsRect(Runner.frame, Water.frame)){
life = life - 1;
Lives.text = #"",life;
Runner.center = CGPointMake(Runner.center.x, Runner.center.y + 100);
}
}
-(IBAction)StartGame:(id)sender{
Start.hidden=YES;
UpMovement = 3;
[self Walk];
Movement = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(Moving) userInfo:nil repeats:YES];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
If Lives is your label, Then it should be as below.
Lives.text =[NSString stringWithFormat:#"%#",life]; /// if life is string
Lives.text =[NSString stringWithFormat:#"%d", life]; /// if life is integer
Replace this with your Method, and it is good to go.
-(void)Moving{
Runner.center = CGPointMake(Runner.center.x, Runner.center.y - UpMovement);
if(CGRectIntersectsRect(Runner.frame, Water.frame)){
life = life - 1;
lives.text = [NSString stringWithFormat:#"%d",life];
// Lives.text = #"",life;
Runner.center = CGPointMake(Runner.center.x, Runner.center.y + 100);
}
}

Resources