Objective c 如何保持视图控制器在后台运行?

Objective c 如何保持视图控制器在后台运行?,objective-c,nstimer,state-management,Objective C,Nstimer,State Management,好的,我的应用程序中有两个视图控制器。第一个是计时器,第二个是秒表。当我在不同的视图之间切换时,如何使计时器继续运行 在我改变视图的那一刻,计时器停止,一切都重置 First views.m文件: #import "ViewController.h" #import <AudioToolbox/AudioToolbox.h> @interface ViewController () //TIMER //labels @property (weak, nonatomic) IBOu

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

在我改变视图的那一刻,计时器停止,一切都重置

First views.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
#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

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

为此,您应该使用
NSDate
记录计时器的启动时间,以便计算计时器运行了多长时间。您需要让计时器真正运行的唯一原因是处理
overall=overall-1


现在,上述内容更加复杂,您需要在处理暂停的方式中添加更多的逻辑(使用
NSTimer
暂停还有其他答案)。但是,它更干净、更准确(计时器的点火率不是100%保证)。

显示您的代码。将视图控制器中的持久逻辑抽象到另一个自定义classI刚刚为不同的视图上载了两个.m文件为什么两个视图显示相同的计时器倒计时标签?为什么没有一个视图用于实时显示(带计时器)和一个视图用于配置(不带计时器/显示UI)?我使用一个用于秒表,另一个用于计时器作为我的第一个应用程序我不确定我在做什么,但我想在我更改屏幕时让它们都继续运行,但我不知道如何操作