2012-05-19 15 views
13

Soy nuevo en la programación de iOS. Estoy trabajando en el juego de emparejar palabras. En este juego necesito implementar un contador de tiempo que muestre minutos y segundos. Quiero que cuando mi juego se inicie mi temporizador comience con 3 minutos. Ahora quiero disminuir este temporizador en dirección inversa con segundos. mi código sólo funciona para seconds..here es mi código:Implementando un temporizador de cuenta regresiva en Objective-c?

secondsLeft--; 

    int seconds = (secondsLeft %3600) % 60; 

    Timerlbl.text = [NSString stringWithFormat:@"%02d",seconds]; 


    if (seconds==0) 

{ 


UIAlertView *pAlert = [[UIAlertView alloc]initWithTitle:@"Sorry!!" 
message:@"TimeOver"  delegate:self cancelButtonTitle:@"OK" 
otherButtonTitles:@"Cancel",nil]; 

[pAlert show]; 

[pAlert release]; 

} 

} 

En viewDidLoad lo llamo a través del temporizador ..

  countDown=[NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
       selector:@selector(TimeOver) userInfo:nil repeats:YES]; 

peticiones cualquiera me guía cómo puedo hacerlo en los dos minutos y segundos.

+0

Consulte el siguiente enlace [Temporizador de cuenta regresiva] (http://fromideatoapp.com/downloads/FI2ADemo-Part4.zip) También es bastante útil. Saludos, Neil – NIKHIL

Respuesta

46

Usted puede hacerlo de esta manera (ARC Habilitado): -

@interface ViewController() 
{ 
UILabel *progress; 
    NSTimer *timer; 
    int currMinute; 
    int currSeconds; 
} 
@end 


@implementation ViewController 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    progress=[[UILabel alloc] initWithFrame:CGRectMake(80, 15, 100, 50)]; 
    progress.textColor=[UIColor redColor]; 
    [progress setText:@"Time : 3:00"]; 
    progress.backgroundColor=[UIColor clearColor]; 
    [self.view addSubview:progress]; 
    currMinute=3; 
    currSeconds=00; 

    // Do any additional setup after loading the view, typically from a nib. 
} 
-(void)start 
{ 
    timer=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerFired) userInfo:nil repeats:YES]; 

} 
-(void)timerFired 
{ 
if((currMinute>0 || currSeconds>=0) && currMinute>=0) 
{ 
    if(currSeconds==0) 
    { 
     currMinute-=1; 
     currSeconds=59; 
    } 
    else if(currSeconds>0) 
    { 
     currSeconds-=1; 
    } 
    if(currMinute>-1) 
    [progress setText:[NSString stringWithFormat:@"%@%d%@%02d",@"Time : ",currMinute,@":",currSeconds]]; 
} 
    else 
    { 
     [timer invalidate]; 
    } 
} 
+0

Gracias Querida @roronoa zorro tu respuesta es la mejor solución que quiero. – jamil

+0

Hola @ roronoa-zorro, me preguntaba cómo lidiar con pausar el temporizador? – gdubs

+0

No se puede hacer una pausa o reiniciar el contador de tiempo, sólo se puede invalidar it.The pausa y reanudación se pueden replicar mediante el uso de una variable NSDate, almacenar el NSDate actual en el momento que desee hacer una pausa (en realidad invalida) y reiniciar el temporizador del salvado Objeto NSDate –

0

Puede usar NSTimer para lograrlo.

+1

Echa un vistazo a este tutorial, te ayudará a lograr lo que quieres - http://pravinmagdum.wordpress.com/tag/nstimer-tutorial/ – rishi

+1

puedes agregar la línea de error completa y también el código donde estás obteniendo este error – rishi

+1

Mira esto, podría ser que esto te está causando un problema - http://stackoverflow.com/questions/2340930/stray-342-in-c-program – rishi

3

En archivo .h

IBOutlet UILabel* lblTimer; 
NSTimer* gameTimer; 

En el archivo .m

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self createTimer]; 
} 

- (void)createTimer 
{  
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop]; 

    gameTimer = [[NSTimer timerWithTimeInterval:1.00 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES] retain]; 
    [[NSRunLoop currentRunLoop] addTimer:gameTimer forMode:NSDefaultRunLoopMode]; 
    timeCount = 20; 
    [runLoop run]; 
    [pool release]; 
} 

- (void)timerFired:(NSTimer *)timer 
{ 
    if(timeCount == 0) 
    { 
     [self timerExpired]; 
    } 
    else 
    { 
     timeCount--; 
     if(timeCount == 0) { 
     [timer invalidate]; 
     [self timerExpired]; 
    } 
} 
    lblTimer.text = [NSString stringWithFormat:@"%02d:%02d",timeCount/60, timeCount % 60]; 
    self.title = lblTimer.text; 
} 

Enlace el anterior salida de etiquetas con la etiqueta en la vista.

Se está trabajando correctamente con mí

+1

NSRunLoop bloqueará el control si está dirigido al evento invocado por la acción de un control UIView 'en particular. –

+0

[temporizador automático expirado]; lo siento, ¿qué método es esta llamada? –

15

Sé que esto es cuestión de edad, pero quiero compartir mi manera de lograr esto . Tenemos el método (timeIntervalSinceDate :) para calcular el intervalo y tenemos una cantidad fija de segundos para la cuenta regresiva. En mi caso 300 s.

actualización de julio, 2015 SWIFT

@IBAction func startTimer(sender: UIButton) { 
    sender.selected = !sender.selected; 
    //if selected fire timer, otherwise stop 
    if (sender.selected) { 
     self.timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("updateTimer"), userInfo: nil, repeats: true); 
     self.startDate = NSDate(); 
    } else { 
     self.stopTimer(); 
    } 

} 

func stopTimer() { 
    self.timer.invalidate(); 
} 

func updateTimer() { 
    // Create date from the elapsed time 
    var currentDate:NSDate = NSDate(); 
    var timeInterval:NSTimeInterval = currentDate.timeIntervalSinceDate(self.startDate!); 

    //300 seconds count down 
    var timeIntervalCountDown = 300 - timeInterval; 
    var timerDate:NSDate = NSDate(timeIntervalSince1970: timeIntervalCountDown); 

    // Create a date formatter 
    var dateFormatter = NSDateFormatter(); 
    dateFormatter.dateFormat = "mm:ss"; 
    dateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0); 

    // Format the elapsed time and set it to the label 
    var timeString = dateFormatter.stringFromDate(timerDate); 
    self.timerLabel?.text = timeString; 
} 

Working github swift sample project

Objective-C

- (void)updateTimer 
{ 
    // Create date from the elapsed time 
    NSDate *currentDate = [NSDate date]; 
    NSTimeInterval timeInterval = [currentDate 
            timeIntervalSinceDate:self.startDate]; 
    NSLog(@"time interval %f",timeInterval); 

    //300 seconds count down 
    NSTimeInterval timeIntervalCountDown = 300 - timeInterval; 

    NSDate *timerDate = [NSDate 
         dateWithTimeIntervalSince1970:timeIntervalCountDown]; 

    // Create a date formatter 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:@"mm:ss"]; 
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]]; 


    // Format the elapsed time and set it to the label 
    NSString *timeString = [dateFormatter stringFromDate:timerDate]; 
    self.stopWatch.text = timeString; 
} 

- (void)stopTimer 
{ 
    [self.stopWatchTimer invalidate]; 
    self.stopWatchTimer = nil; 
    [self updateTimer]; 

} 

- (void)startTimer 
{ 

    if (self.stopWatchTimer) { 
     [self.stopWatchTimer invalidate]; 
     self.stopWatchTimer = nil; 
    } 

    self.startDate = [NSDate date];  

    // Create the stop watch timer that fires every 100 ms 
    self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0 
              target:self 
             selector:@selector(updateTimer) 
             userInfo:nil 
              repeats:YES]; 
} 

UPDATE:

es extremadamente costoso crear un NSDateFormatter cada vez que pasa a updateTimer. Es mucho mejor crear NSDateFormatter fuera del ciclo y reutilizarlo. Créditos: @siburb

+2

¡Gracias por esto! Esto es realmente bueno. – ullstrm

+0

En caso de que alguien vaya a copiar/pegar esto textualmente (usted sabe quién es usted), es extremadamente costoso crear un 'NSDateFormatter' cada vez que pase por' updateTimer'. Es mucho mejor crear el 'NSDateFormatter' fuera del ciclo y reutilizarlo. – siburb

+0

@siburb, punto justo, incluirá su comentario en la actualización –

Cuestiones relacionadas