2016-01-06 32 views
0

我已经实现了一个简单的倒计时UIDatePickerNSTimeInterval它工作正常,但我有以下问题:当我在Xcode模拟器中运行应用程序,如果我按Ctrl + shift + h,倒计时在后台工作,但是当我在iPhone 6上运行应用程序时,如果按下主屏幕按钮,倒计时将停止,并且不会在后台工作。iOS中的倒数计时器在后台不工作

我已实现了以下通知(AppDelegate.m):

- (void)applicationWillResignActive:(UIApplication *)application { 
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"didEnterBackground" object:nil]; 

} 

- (void)applicationDidBecomeActive:(UIApplication *)application { 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"didEnterForeground" object:nil]; 

} 

在ViewController.m的代码是:

- (void)viewDidLoad { 

    self.mensajeCuenta.hidden = YES; 
    self.botonDetenerCuenta.hidden = YES; 

    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteredBackground:) name:@"didEnterBackground" object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteredForeground:) name:@"didEnterForeground" object:nil]; 
    estaActivo = false; 
    cuentaAtras = 0.0; 

} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
    // Release any retained subviews of the main view. 
    if ([tiempo isValid]) { 
     [tiempo invalidate]; 
    } 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } else { 
     return YES; 
    } 
} 

- (IBAction)botonIniciarCuenta:(id)sender { 



    cuentaAtras = (NSTimeInterval)_vistaContador.countDownDuration; 
    remainder = cuentaAtras; 
    //NSLog(@"Total de segundos: %i", remainder); 
    afterRemainder = cuentaAtras - remainder%60; 
    //NSLog(@"Total segundos despues restantes: %i", afterRemainder); 


    tiempo = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(actualizarCuentaAtras) userInfo:nil repeats:YES]; 

} 

- (IBAction)botonDetenerCuenta:(id)sender { 


    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"La cuenta atrás se ha parado" message:@"Pulse Iniciar para una nueva cuenta" preferredStyle:UIAlertControllerStyleAlert]; 

    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"Aceptar" style:UIAlertActionStyleDefault 
                  handler:^(UIAlertAction * action) {}]; 

    [alert addAction:defaultAction]; 
    [self presentViewController:alert animated:YES completion:nil]; 

    [self visibilidadBotones]; 
    [tiempo invalidate]; 
    tiempo = nil; 


} 

- (void)actualizarCuentaAtras { 

    self.botonIniciarCuenta.hidden = YES; 
    self.mensajeCuenta.hidden = NO; 
    self.tiempoRestante.hidden = NO; 
    self.botonDetenerCuenta.hidden = NO; 

    dispatch_async(dispatch_get_main_queue(), ^{ 

    if (afterRemainder >= 0) { 
     afterRemainder--; 


     //NSLog(@"Valor restante disminuido: %i", afterRemainder); 

     int horas = (int)(afterRemainder/(60*60)); 
     int minutos = (int)(((int)afterRemainder/60)- (horas * 60)); 
     int segundos = (int)(((int)afterRemainder - (60 * minutos) - (60 * horas * 60))); 

     NSString *cadenaTiempo = [[NSString alloc]initWithFormat:@"%02u : %02u : %02u", horas, minutos, segundos]; 

     self.tiempoRestante.text = cadenaTiempo; 

     if (afterRemainder == 0) { 

      [tiempo invalidate]; 
      tiempo = nil; 
      [self visibilidadBotones]; 
      [self enviarAlerta]; 
     } 
    } 

    }); 



} 

- (void)enteredBackground:(NSNotification *)notification 
{ 
    if (estaActivo) { 
     [tiempo invalidate]; 
     date = [NSDate dateWithTimeIntervalSinceNow:cuentaAtras]; 
     //NSLog([date description]); 
     self.notification = [[UILocalNotification alloc] init]; 
     self.notification.fireDate = date; 
     self.notification.timeZone = [NSTimeZone defaultTimeZone]; 
     self.notification.alertAction = @"timer fired"; 
     self.notification.alertBody = @"timer fired!"; 
     self.notification.soundName = UILocalNotificationDefaultSoundName; 
     [[UIApplication sharedApplication] scheduleLocalNotification:self.notification]; 
    } 
} 

- (void)enteredForeground:(NSNotification *)notification 
{ 
    if (estaActivo) { 
     NSTimeInterval newDuration = [self.notification.fireDate timeIntervalSinceNow]; 
     if (newDuration > 0.0) { 
      cuentaAtras = newDuration; 
      tiempo = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(actualizarCuentaAtras) userInfo:nil repeats:YES]; 
     } else { 
      cuentaAtras = 0.0; 
      //[self.countDownPicker setHidden:NO]; 
      //[self.countDownLabel setHidden:YES]; 
      estaActivo = !estaActivo; 
     } 
     [self actualizarCuentaAtras]; 
     [[UIApplication sharedApplication] cancelLocalNotification:self.notification]; 
    } 
} 

- (void)enviarAlerta { 


    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Notificación enviada" message:@"Puede reiniciar la cuenta atrás" preferredStyle:UIAlertControllerStyleAlert]; 

    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"Aceptar" style:UIAlertActionStyleDefault 
                  handler:^(UIAlertAction * action) {}]; 

    [alert addAction:defaultAction]; 
    [self presentViewController:alert animated:YES completion:nil]; 
} 

-(void)visibilidadBotones { 

    self.botonIniciarCuenta.hidden = NO; 
    self.botonDetenerCuenta.hidden = YES; 
    self.mensajeCuenta.hidden = YES; 
    self.tiempoRestante.hidden = YES; 

} 
@end 

在ViewController.h的代码是:

@interface ViewController : UIViewController { 

    int afterRemainder; 
    int remainder; 
    NSTimeInterval cuentaAtras; 
    NSTimer *tiempo; 
    BOOL estaActivo; 
    NSDate *date; 
} 


@property (strong, nonatomic) IBOutlet UIDatePicker *vistaContador; 

@property (strong, nonatomic) IBOutlet UILabel *mensajeCuenta; 

- (IBAction)botonIniciarCuenta:(id)sender; 
@property (strong, nonatomic) IBOutlet UIButton *botonIniciarCuenta; 


- (IBAction)botonDetenerCuenta:(id)sender; 
@property (strong, nonatomic) IBOutlet UIButton *botonDetenerCuenta; 

@property (strong, nonatomic) IBOutlet UILabel *tiempoRestante; 

@property (strong, nonatomic) UILocalNotification *notification; 

我开始在iOS中编程,并且在后台为我控制进程非常复杂,但是我不明白为什么倒计时在Xcode模拟器中工作,并且不适用于我的iPhone?

怎么了?

回答

1

定时器不会在后台运行,除非您利用其他一些背景模式。

处理此问题的最佳方法是在applicationWillResignActive中暂停并记下当前时间,然后在applicationDidBecomeActive中重新启动它,减去暂停后的时间。

+0

你可以使用示例代码?谢谢!! :) –