NSTimer responding to a uibutton - ios

So, Here is the problem. I am trying to make a timer for my game however it doesnt seem to run.
I started by making a property for nstimer:
#property (nonatomic) NSTimer gameTimer;
and synthesizing it:
#synthesize gameTimer = _gameTimer;
then I use this method to set it:
-(NSTimer *) gameTimer{
if (_gameTimer == nil) _gameTimer = [[NSTimer alloc]init];
return _gameTimer;
}
however when i try to start the timer through a uibutton:
- (IBAction)play:(UIButton *)sender {
_levelNumber = 1;
_en1v = -1;
_en2v = 1;
_en3v = -1;
[self setPath];
_gameTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(onTimer:) userInfo:nil repeats:YES];
self.play.hidden = TRUE;
}
it doesn't work.
I put an nslog into the onTimer: method and found out that the timer just isn't firing some how?
Am I making an obvious mistake?

You have not started the timer at all.
Use:
_gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(onTimer:) userInfo:nil repeats:YES];
And while stopping, (may be in stop: method)
[_gameTimer invalidate];
_gameTimer = nil;

Related

Values from 1 to 100 in label change when view is loaded in objective c

I want to show user that the value initially is 0 than it increase to 1 than 2 than 3 sequence repeat after some seconds
Worked done by me
I write this code in viewdidload but it print 99 in label directly but i want to show user changing values from 0 to 99.
for(int i=0;i<100;i++){
_totalEffort.text=[NSString stringWithFormat:#"%d",i];
}
I think this will help you:
#interface ViewController (){
int i;
NSTimer *myTimer;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(setData)
userInfo:nil
repeats:YES];
i = 0;
}
-(void)setData{
_totalEffort.text=[NSString stringWithFormat:#"%d",i];
i = i + 1;
if(i == 100){
[myTimer invalidate];
myTimer = nil;
}
}
Based on your requirement you need to use NSTimer for update your label progress
Step 1: Create 2 variable in your #interface class
#interface BUViewController: UIViewController {
NSTimer *timerCount;
int progress;
}
Step 2: Start Timer in your viewDidLoad() with progress value 0.
progress = 0;
timerCount = [NSTimer timerWithTimeInterval:0.5 target:self selector:#selector(updateLabel) userInfo:nil repeats:YES];
Step 3: create method with timer update label text an check progress value in it and stop timer while its reach 100.
-(void)updateLable{
if (progress<100) {
lblProgress.text = [NSString stringWithFormat:#"%d",progress];
progress++;
}else{
[timerCount invalidate];
timerCount = nil;
}
}
Hope this will help you to achieve your expected output.
For this you can use NSTimer you need to update UILabel value in its selector method. You can use this code.
-(void)viewDidLoad{
[super viewDidLoad];
self.time = 0;
_labelTimer.text =#"0";
[self startTimer];
}
- (void)startTimer {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerAction:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
}
- (void)timerAction:(NSTimer *)timer {
self.time++;
if (self.time == 100)
{
[self stopTimer];
}
_labelTimer.text = [NSString stringWithFormat:#"%d",self.time];
}
-(void)stopTimer{
[self.timer invalidate];
self.timer = nil;
}
Here is code for your problem .hope it helps you.
- (void)viewDidLoad
{
[super viewDidLoad];
counter = 0;
t = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(updateLabel) userInfo:nil repeats:YES];
}
-(void)updateLabel
{
for (int i = counter; i<counter+1; i++)
{
_totalEffort.text=[NSString stringWithFormat:#"%d",i];
}
counter++;
if (counter ==101)
{
[t invalidate];
}
}
You are blocking run loop with your cycle. You just need resume it in each iteration.
for(int i=0;i<100;i++){
_totalEffort.text=#(i).stringValue;
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}

Slow down NSTimer with a for loop in Objective-C

I have a button that when pressed generates random numbers triggered by NSTimer at a certain frequency, and when released I would like it to keep generating them, just more slower and slower until it stops.
- (void)buttonPressed {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:#selector(generateNumber) userInfo:nil repeats:YES];
}
- (void)buttonReleased {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
for (float i=0.20; i<1; i += 0.1) {
_timer = [NSTimer scheduledTimerWithTimeInterval:i target:self selector:#selector(generateNumber) userInfo:nil repeats:NO];
}
}
It works fine while the button is pressed, but once I release it actually accelerate and then stops all in a sudden. Any idea why it wouldn't be working or any alternative way I can reach the wanted result?
Once your button is released, generation accelerates because at that moment you schedule 8 timers with intervals 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 and 0.9 starting at the time of button release, which means each will execute 0.1s after the other, which is a smaller interval than your original timer (0.2s).
This is an alternative
#interface ViewController ()
#property (nonatomic, retain) NSTimer *timer;
#property (nonatomic) float curInterval;
#end
#implementation ViewController
- (IBAction)buttonDown {
self.curInterval = 0.1;
[self updatePressed];
}
- (void)updatePressed {
[self generateNumber];
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.curInterval target:self selector:#selector(updatePressed) userInfo:nil repeats:NO];
}
- (IBAction)buttonUp {
[self.timer invalidate];
[self updateUp];
}
- (void)updateUp {
[self generateNumber];
self.curInterval += 0.1;
if (self.curInterval < 1.0f) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.curInterval target:self selector:#selector(updateUp) userInfo:nil repeats:NO];
}
}
#end
In Button release method you are using for loop which keeps on executing untill it reaches interval of 1. What you need to do is take a global float value and initialize it to 0.20 at start. On button pressed pass that value. On button release increment the global variable and pass that value to NSTimer instead of for loop
float numTimer = 0.20f;
- (void)buttonPressed {
_timer = [NSTimer scheduledTimerWithTimeInterval:numTimer target:self selector:#selector(generateNumber) userInfo:nil repeats:YES];
}
- (void)buttonReleased {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
numTimer = numTimer + 0.1f;
_timer = [NSTimer scheduledTimerWithTimeInterval:numTimer target:self selector:#selector(reGenerateNumber) userInfo:nil repeats:NO]; }
}
-(void) reGenerateNumber {
[self generateNumber];
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
numTimer = numTimer + 0.1f;
_timer = [NSTimer scheduledTimerWithTimeInterval:numTimer target:self selector:#selector(reGenerateNumber) userInfo:nil repeats:NO];
}

How to toggle the visibility of buttons with a timer?

Ive added an NSTimer to make my rate button appear by setting the action to Hidden NO
NSMethodSignature *sgn = [self methodSignatureForSelector:#selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:#selector(onTick:)];
NSTimer *t = [NSTimer timerWithTimeInterval: 10.0
invocation:inv
repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];
Then
-(void)onTick:(NSTimer *)timer {
_Rateapp1.hidden = NO;
_ratebomb.hidden = NO;
_ratelab1.hidden = NO;
}
BUT how do I make the button re-Appear with YES?
Assuming your goal is to toggle the display of the buttons each time the timer goes off, you simply do:
- (void)onTick:(NSTimer *)timer {
_Rateapp1.hidden = !_Rateapp1.hidden;
_ratebomb.hidden = !_ratebomb.hidden;
_ratelab1.hidden = !_ratelab1.hidden;
}
And you can replace all of your timer creation code with:
NSTimer *t = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:#selector(onTick:) userInfo:nil repeats:YES];
No need for the invocation or runloop code. I also suggest you keep a reference to the timer so you can invalidate (stop) the timer when needed.

how to fire timer when create the timer inside block function?

#interface Taxi_MainViewController : Taxi_BaseNavViewController
{
__block NSTimer *timer_;
}
[Taxi_do_order psg_place_orderWithMemberId:strMemberId_ orderStatus:K_orderStatus_open andCLLocationCoord:location.coordinate callback:^(NSInteger iOrderId){
[Taxi_StatusView dismiss];
if (iOrderId >=0)
{
isOrderExist = YES;
[weakSelf_ showWaittingDriverAcceptView];
timer_ = [NSTimer scheduledTimerWithTimeInterval:2.0
target:weakSelf_
selector:#selector(actListen:)
userInfo:nil
repeats:YES];
}else
[weakSelf_ hideWaittingDriverAcceptView];
}faile:^(){
[Taxi_StatusView showLostNetWork];
}];
when i call [timer_ invalidate],timer_ = nil; at other method, the timer function still call every 2 second.
In your case, the variable timer_ is never keep, and you lose the pointer
at the end block scope. With a property you have retain / release mechanism.
Try this :
#interface Taxi_MainViewController : Taxi_BaseNavViewController
{
}
#property (nonatomic,retain) NSTimer* timer;
#end
[Taxi_do_order psg_place_orderWithMemberId:strMemberId_ orderStatus:K_orderStatus_open andCLLocationCoord:location.coordinate callback:^(NSInteger iOrderId){
[Taxi_StatusView dismiss];
if (iOrderId >=0)
{
isOrderExist = YES;
[weakSelf_ showWaittingDriverAcceptView];
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0
target:weakSelf_
selector:#selector(actListen:)
userInfo:nil
repeats:YES];
}else
[weakSelf_ hideWaittingDriverAcceptView];
}faile:^(){
[Taxi_StatusView showLostNetWork];
}];

How to pause a NSTimer? [duplicate]

This question already has answers here:
How can I programmatically pause an NSTimer?
(16 answers)
Closed 9 years ago.
I have a game which uses a timer. I want to make it so the user can select a button and it pauses that timer and when they click that button again, it will unpause that timer. I already have code to the timer, just need some help with the pausing the timer and the dual-action button.
Code to timer:
-(void)timerDelay {
mainInt = 36;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(countDownDuration)
userInfo:nil
repeats:YES];
}
-(void)countDownDuration {
MainInt -= 1;
seconds.text = [NSString stringWithFormat:#"%i", MainInt];
if (MainInt <= 0) {
[timer invalidate];
[self delay];
}
}
That's very easy.
// Declare the following variables
BOOL ispaused;
NSTimer *timer;
int MainInt;
-(void)countUp {
if (ispaused == NO) {
MainInt +=1;
secondField.stringValue = [NSString stringWithFormat:#"%i",MainInt];
}
}
- (IBAction)start1Clicked:(id)sender {
MainInt=0;
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countUp) userInfo:Nil repeats:YES];
}
- (IBAction)pause1Clicked:(id)sender {
ispaused = YES;
}
- (IBAction)resume1Clicked:(id)sender {
ispaused = NO;
}
There is no pause and resume functionality in NSTimer. You can impliment it like below code.
- (void)startTimer
{
m_pTimerObject = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(fireTimer:) userInfo:nil repeats:YES];
}
- (void)fireTimer:(NSTimer *)inTimer
{
// Timer is fired.
}
- (void)resumeTimer
{
if(m_pTimerObject)
{
[m_pTimerObject invalidate];
m_pTimerObject = nil;
}
m_pTimerObject = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(fireTimer:) userInfo:nil repeats:YES];
}
- (void)pauseTimer
{
[m_pTimerObject invalidate];
m_pTimerObject = nil;
}

Resources