【问题标题】:iOS app Stopwatch and Timer stop counting when in backgroundiOS 应用秒表和计时器在后台停止计数
【发布时间】:2024-01-11 06:44:02
【问题描述】:

我有一个基本上是时钟、秒表和计时器的 iPhone 应用程序。一切正常,直到您离开应用程序,秒表和计时器停止计数。我认为解决这个问题的方法是在应用程序进入后台时启动一个计数器,并在应用程序再次启动时从秒表/计时器中添加/减去它。这是最好的做法吗?如果是,我该怎么做?

更新:计时器、秒表和时钟都在不同的视图控制器中。这是我的秒表在 StopwatchViewController.m 中的代码:

- (void)stopwatch // Start counting the stopwatch
{
    hourInt = [hourLabel.text intValue];     // Store integer values of time
    minuteInt = [minuteLabel.text intValue];
    secondInt = [secondLabel.text intValue];

    if (secondInt == 59) {                   // Add on one second
        secondInt = 0;
        if (minuteInt == 59) {
            minuteInt = 0;
            if (hourInt == 23) {
                hourInt = 0;
            } else {
                hourInt += 1;
            }
        } else {
            minuteInt += 1;
        }
    } else {
        secondInt += 1;
    }

    NSString *hourString = [NSString stringWithFormat:@"%02d", hourInt];     // Update text to show time
    NSString *minuteString = [NSString stringWithFormat:@"%02d", minuteInt];
    NSString *secondString = [NSString stringWithFormat:@"%02d", secondInt];

    hourLabel.text = hourString;
    minuteLabel.text = minuteString;
    secondLabel.text = secondString;

    [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(stopwatch) userInfo:nil repeats:NO]; // Repeat every second
}

如何让它添加应用程序在后台运行的时间?

【问题讨论】:

    标签: ios objective-c timer


    【解决方案1】:

    为应用何时进入后台和应用进入ForeGround添加两个观察者

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterInBackGround) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterInForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
    
    
    - (void)applicationWillEnterInBackGround{
          // stop your timer here
    }
    
    - (void)applicationWillEnterInForeground
    {
         // start your timer here
    }
    

    示例 ------

    在.h中

    NSTimer *timer;
    float time;
    

    在.m

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        timer=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(stopwatch) userInfo:nil repeats:YES];
    
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterInBackGround) name:UIApplicationWillResignActiveNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterInForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
    }
    
    - (void)applicationWillEnterInBackGround
    {
        [timer invalidate];
    }
    
    - (void)applicationWillEnterInForeground
    {
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(stopwatch) userInfo:nil repeats:YES];
    }
    
    - (void)stopwatch // Start counting the stopwatch
    {
        hourInt = [hourLabel.text intValue];     // Store integer values of time
        minuteInt = [minuteLabel.text intValue];
        secondInt = [secondLabel.text intValue];
    
        if (secondInt == 59) {                   // Add on one second
            secondInt = 0;
            if (minuteInt == 59) {
                minuteInt = 0;
                if (hourInt == 23) {
                    hourInt = 0;
                } else {
                    hourInt += 1;
                }
            } else {
                minuteInt += 1;
            }
        } else {
            secondInt += 1;
        }
    
        NSString *hourString = [NSString stringWithFormat:@"%02d", hourInt];     // Update text to show time
        NSString *minuteString = [NSString stringWithFormat:@"%02d", minuteInt];
        NSString *secondString = [NSString stringWithFormat:@"%02d", secondInt];
    
        hourLabel.text = hourString;
        minuteLabel.text = minuteString;
        secondLabel.text = secondString;
    }
    

    【讨论】:

    • 我应该把观察者放在哪里?我应该在 applicationWillEnterInBackGround 和 applicationWillEnterInForeGround 中创建一个 NSDate,我应该计算自该日期以来的时间吗?我对 Objective-C 很陌生,所以我不太了解它!
    • @user2397282 如果您仍然遇到任何问题,请在此处发布您的问题。
    • 好的,我尝试复制你的代码,但它似乎没有任何作用?
    【解决方案2】:

    当应用程序进入后台然后返回前台时继续保存当前时间的最简单方法是计算时间间隔并将其添加到您的计数器中,例如:

    .. going background ..
    
    NSDate *backgroundTime = [[NSDate date] retain];
    
    .. returning foreground ..
    
    NSTimeInterval elapsed = [NSDate timeIntervalSinceDate:date];
    [date release];
    yourTimer -= elapsed;
    

    要了解何时应该挂钩这些事件,您应该查看here

    【讨论】: