2016-01-06 122 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

你可以使用示例代碼?謝謝!! :) –