如何让视图控制器在后台运行?

时间:2014-04-30 14:09:05

标签: objective-c nstimer state-management

好的,我的应用程序中有两个视图控制器。第一个是计时器,第二个是秒表。当我在它们之间切换时,如何让计时器继续观察不同的视图?

当我改变视图时,计时器停止并且一切都重置。

首先观看.m文件:

#import "ViewController.h"
#import <AudioToolbox/AudioToolbox.h>

@interface ViewController ()

//TIMER
//labels
@property (weak, nonatomic) IBOutlet UILabel *timeLabelHour;
@property (weak, nonatomic) IBOutlet UILabel *timeLabelMin;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
//buttons
@property (weak, nonatomic) IBOutlet UIBarButtonItem *timerWindow;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *stopwatchWindow;
@property (weak, nonatomic) IBOutlet UIButton *stop;
@property (weak, nonatomic) IBOutlet UIButton *start;
@property (weak, nonatomic) IBOutlet UIButton *reset;
//steppers
@property (weak, nonatomic) IBOutlet UIStepper *stepper;
@property (weak, nonatomic) IBOutlet UIStepper *Minstepper;
@property (weak, nonatomic) IBOutlet UIStepper *Hourstepper;




@end

@implementation ViewController

-(void) timerRun{

if(pause == NO){
    overall = overall - 1;



    int hours = overall / 3600;
    int minutes = overall - (hours * 3600);
    int minCon = minutes / 60;
    int seconds = minutes - (minCon * 60);

    NSString *timerOutputHour = [NSString stringWithFormat:@"%d", hours];
    NSString *timerOutputMin = [NSString stringWithFormat:@"%02d", minCon];
    NSString *timerOutput = [NSString stringWithFormat:@"%02d", seconds];

    self.timeLabelHour.text = timerOutputHour;
    self.timeLabelMin.text = timerOutputMin;
    self.timeLabel.text = timerOutput;


    if(overall == 0){

        [Countdown invalidate];
        Countdown = nil;

        UILocalNotification *timeFinNotification = [[UILocalNotification alloc] init];
        timeFinNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow: 1];
        timeFinNotification.alertBody = @"Your timer has finished";
        timeFinNotification.timeZone = [NSTimeZone defaultTimeZone];
        [[UIApplication sharedApplication] scheduleLocalNotification:timeFinNotification];

        AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);

        self.Hourstepper.enabled = YES;
        self.Minstepper.enabled = YES;
        self.stepper.enabled = YES;

        timer = 0;
        timerMin = 0;

        self.start.enabled = YES;
        self.stop.enabled = NO;
        self.reset.enabled = NO;

    }
}

}

-(void) setTimer{

overall = (timerMin * 60) + (timerHour * 60 * 60) + timer;


Countdown = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerRun) userInfo:nil repeats:YES];

self.Hourstepper.enabled = NO;
self.Minstepper.enabled = NO;
self.stepper.enabled = NO;


}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

self.stepper.autorepeat = YES;
self.stepper.wraps = YES;
self.stepper.minimumValue = 0;
self.stepper.maximumValue = 59;
self.stepper.stepValue = 1;

self.Minstepper.autorepeat = YES;
self.Minstepper.wraps = YES;
self.Minstepper.minimumValue = 0;
self.Minstepper.maximumValue = 59;
self.Minstepper.stepValue = 1;

self.Hourstepper.autorepeat = YES;
self.Hourstepper.wraps = YES;
self.Hourstepper.minimumValue = 0;
self.Hourstepper.maximumValue = 23;
self.Hourstepper.stepValue = 1;

self.start.enabled = YES;
self.stop.enabled = NO;
self.reset.enabled = NO;

timer = self.stepper.value;
timerMin = self.Minstepper.value;
timerHour = self.Hourstepper.value;


}



- (IBAction)start:(id)sender{
if(pause == NO && (timer != 0 || timerMin != 0 || timerHour != 0)){
    [self setTimer];
}
pause = NO;
if(timer != 0 || timerMin != 0 || timerHour != 0){
    self.start.enabled = NO;
    self.stop.enabled = YES;
    self.reset.enabled = YES;
}

}

- (IBAction)stop:(id)sender{
pause = YES;
self.start.enabled = YES;
self.stop.enabled = NO;
self.reset.enabled = YES;
}

- (IBAction)reset:(id)sender{

[Countdown invalidate];
Countdown = nil;


self.Hourstepper.enabled = YES;
self.Minstepper.enabled = YES;
self.stepper.enabled = YES;

self.timeLabelHour.text = @"0";
self.timeLabelMin.text = @"00";
self.timeLabel.text = @"00";

self.stepper.value = 0;
self.Minstepper.value = 0;
self.Hourstepper.value = 0;

timer = 0;
timerMin = 0;
timerHour = 0;

pause = NO;

self.start.enabled = YES;
self.stop.enabled = NO;
self.reset.enabled = NO;
}

- (IBAction)stepperValueChanged:(UIStepper *)sender
{
timer = sender.value;
self.timeLabel.text = [NSString stringWithFormat:@"%02d",timer];
}

- (IBAction)stepperValueChangedMin:(UIStepper *)sender
{
timerMin = sender.value;
self.timeLabelMin.text = [NSString stringWithFormat:@"%02d",timerMin];
}

- (IBAction)stepperValueChangedHour:(UIStepper *)sender
{
timerHour = sender.value;
self.timeLabelHour.text = [NSString stringWithFormat:@"%d",timerHour];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}


#pragma mark iAd Delegate Mathods

-(void)bannerViewDidLoadAd:(ADBannerView *)banner{

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:1];
[UIView commitAnimations];

}

-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:0];
[UIView commitAnimations];

}

@end

Second Views .m文件:

#import "ViewControllerStopwatch.h"

@interface ViewControllerStopwatch ()

//STOPWATCH
//labels
@property (weak, nonatomic) IBOutlet UILabel *stopLabelHour;
@property (weak, nonatomic) IBOutlet UILabel *stopLabelMin;
@property (weak, nonatomic) IBOutlet UILabel *stopLabel;
@property (weak, nonatomic) IBOutlet UILabel *stopLabelMilli;

//buttons
@property (weak, nonatomic) IBOutlet UIBarButtonItem *timerWindow;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *stopwatchWindow;
@property (weak, nonatomic) IBOutlet UIButton *start;
@property (weak, nonatomic) IBOutlet UIButton *reset;
@property (weak, nonatomic) IBOutlet UIButton *stop;


@end

@implementation ViewControllerStopwatch

-(void) timerRun{

if(pause == NO){


    overall = overall + 1;

    hours = overall / 3600;
    minutes = overall - (hours * 3600);
    minCon = minutes / 60;
    seconds = minutes - (minCon * 60);

    NSString *timerOutputHour = [NSString stringWithFormat:@"%d", hours];
    NSString *timerOutputMin = [NSString stringWithFormat:@"%02d", minCon];
    NSString *timerOutput = [NSString stringWithFormat:@"%02d", seconds];

    self.stopLabelHour.text = timerOutputHour;
    self.stopLabelMin.text = timerOutputMin;
    self.stopLabel.text = timerOutput;

}

}

-(void) timerRunMilli{

if(pause == NO){


    overallMilli = overallMilli + 1;

    milliseconds = overallMilli;

    if(overallMilli >= 99){
        overallMilli = 0;
    }

    NSString *timerOutputMilli = [NSString stringWithFormat:@"%02d", milliseconds];

    self.stopLabelMilli.text = timerOutputMilli;

}

}

-(void) setTimer{

Countdown = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerRun) userInfo:nil repeats:YES];

CountdownMilli = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(timerRunMilli) userInfo:nil repeats:YES];
}


- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.

self.start.enabled = YES;
self.stop.enabled = NO;
self.reset.enabled = NO;


}

- (IBAction)start:(id)sender{
if(pause == NO){
    [self setTimer];
}
pause = NO;

self.start.enabled = NO;
self.stop.enabled = YES;
self.reset.enabled = YES;


}
- (IBAction)stop:(id)sender{
pause = YES;

self.start.enabled = YES;
self.stop.enabled = NO;
self.reset.enabled = YES;
}

- (IBAction)reset:(id)sender{

[Countdown invalidate];
Countdown = nil;

[CountdownMilli invalidate];
CountdownMilli = nil;


self.stopLabelHour.text = @"0";
self.stopLabelMin.text = @"00";
self.stopLabel.text = @"00";
self.stopLabelMilli.text = @"00";

overall = 0;
overallMilli = 0;

pause = NO;


self.start.enabled = YES;
self.stop.enabled = NO;
self.reset.enabled = NO;
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark iAd Delegate Mathods

-(void)bannerViewDidLoadAd:(ADBannerView *)banner{

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:1];
[UIView commitAnimations];

}

-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:0];
[UIView commitAnimations];

}



@end

1 个答案:

答案 0 :(得分:0)

您不应该在未显示的视图中保持计时器运行。当视图消失时,应停止计时器,当视图出现时(如果计时器应该运行),应重新启动计时器。

为此,您应该使用NSDate来记录计时器何时启动,以便您可以计算它的运行时间。您需要保持计时器正常运行的唯一原因是处理overall = overall - 1;

现在,上面的内容更加复杂,您需要在处理暂停的过程中添加更多逻辑(还有其他答案可以在SO上暂停NSTimer)。但是,它更清洁,更准确(计时器点火率不是100%保证)。