Got an issue with my countdown timer who don't want to countdown from 60 and reset when 0 is reached. At the moment it just sets its label 0 and start counting down to -1, 2-... How do I get it to start from 60 on iOS in xcode?
.m file
#import "ViewController.h"
#interface ViewController ()
{
int timeTick;
NSTimer *timer;
}
#end
#implementation ViewController
- (IBAction)stopStartBtn:(id)sender {
[timer invalidate];
timeTick = 3;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
}
-(void)myTicker{
timeTick--;
NSString *timeString =[[NSString alloc] initWithFormat:#"%d", timeTick];
self.display.text = timeString;
if(timer >= 0){
[timer invalidate];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
timeTick = 3;
}
#end
.h File
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *display;
- (IBAction)stopStartBtn:(id)sender;
#end
Your code currently starts the timer at 0, decrements it, and then checks it it has reached 60. Obviously that won't happen.
If you want to start at 60 and stop at 0 then you need to set timeTick to 60 in viewDidLoad and check for a value of 0 in myTicker.
And don't forget to call [super viewDidLoad]; in your viewDidLoad method.
You also need to fix your check to see if you've reached zero. Right now you are looking at the timer pointer instead of timeTick integer.
Change:
if(timer >= 0){
[timer invalidate];
}
to:
if (timeTick <= 0) {
[timer invalidate];
}
You are also never setting your timer instance variable. You actually set a local variable of the same name.
Change:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
to:
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
#interface Ovning1 ()
{
int timeTick;
NSTimer *timer;
}
#end
#implementation Ovning1
- (IBAction)stopStartBtn:(id)sender {
[timer invalidate];
timeTick = 60;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(myTicker) userInfo:nil repeats:YES];
}
-(void)myTicker{
timeTick--;
NSString *timeString =[[NSString alloc] initWithFormat:#"%d", timeTick];
self.display.text = timeString;
if(timeTick <= 0){
[timer invalidate];
}
}
Related
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]];
}
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];
}
I am sending users location to the server through web service, in the response I get interval to send next location. I am using the following call to send locations using timer but when I get the different value the timer still uses the old value. I also tried to invalidate the timer to set the new value but seems not working
I have global variable
long counter= 10;
self.timer = [NSTimer scheduledTimerWithTimeInterval:counter target:self selector:#selector(updateLocation) userInfo:nil repeats:YES];
- (void)updateLocation {
CLLocation *location = self.locationManager.location;
....
counter = 30;
}
I followed the couple of post from stack overflow but did not get it working.
In short, I need to send the updated location based on the response!
#interface MyClass()
#property (strong, nonatomic) NSTimer *timer;
#property (nonatomic) CGFloat counter;
#end
#implementation MyClass
- (void)viewDidLoad
{
[super viewDidLoad];
//set initial value for timer
self.counter = 10;
[self resetTimer];
}
//...
- (void)resetTimer
{
[self.timer invalidate]
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.counter target:self selector:#selector(updateLocation) userInfo:nil repeats:NO];
}
- (void)updateLocation
{
CLLocation *location = self.locationManager.location;
//...
self.counter = 30;
[self resetTimer];
}
//...
- (void)dealloc
{
//invalidate timer to avoid zombie objects (EXC_BAD_ACCESS crash)
[self.timer invalidate];
}
#end
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
#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];
}];