为在视图控制器之间持续存在的 iOS 应用程序显示计时器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12534074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:18:25  来源:igfitidea点击:

Display a timer for an iOS app that persists between view controllers

iosobjective-ccocoa-touchnstimer

提问by user1677210

I've been trying to get a timer to show at the bottom left corner of my app by using an NSTimer, and making the "elapsed time" show as UILabelon the bottom left corner but it hasn't been working for me.

我一直试图通过使用NSTimer,让一个计时器显示在我的应用程序的左下角,并使“经过的时间”显示UILabel在左下角,但它对我没有用。

-(void)viewDidLoad
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

-(void)aTime
{
    NSLog(@"....Update Function Called....");

    static int i = 1;

    Label.text = [NSString stringWithFormat:@"%d",i];

    i++;
}

The timer actually works but I can't get it to be triggered by a button. I'm trying to get the timer to continue and not restart at 1 when it enters to the next storyboard/xib file.

计时器实际上可以工作,但我无法通过按钮触发它。我试图让计时器继续,而不是在它进入下一个故事板/xib 文件时从 1 重新启动。

回答by Midhun MP

For implementing the timer action on the button press, you need to write it on a IBActionmethod like:

要在按钮按下时实现计时器操作,您需要将其编写在如下IBAction方法中:

- (IBAction) buttonPress
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

For storing the previous value, you can use NSUserDefaultsor a SQLite database. For this purpose I'll suggest NSUserDefaults.

为了存储以前的值,您可以使用NSUserDefaults或 SQLite 数据库。为此,我会建议NSUserDefaults.

Change the aTime method like:

更改 aTime 方法,如:

-(void)aTime
{
    NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
    id obj = [standardUserDefaults objectForKey:@"TimerValue"];
    int i = 0;

    if(obj != nil)
    {
        i = [obj intValue];
    }

    Label.text = [NSString stringWithFormat:@"%d",i];
    i++;

    [standardUserDefaults setObject:[NSNumber numberWithInt:i] forKey:@"TimerValue"];
    [standardUserDefaults synchronize];
}

回答by CarmeloS

I think the problem is that the method aTimeis in your view controller, when you enters another view, this view controller is released and you can't perform selector aTime anymore.

我认为问题在于该方法aTime在您的视图控制器中,当您进入另一个视图时,该视图控制器被释放并且您不能再执行选择器 aTime 了。

so I suggest that you put your aTimemethod and ito a singleton(or any object that won't be released when you enter another view) and set the singleton as the target of your timer.

所以我建议你把你的aTime方法和i一个单例(或任何在你进入另一个视图时不会被释放的对象)设置为你的计时器的目标。

also you should keep code below in your view controller so that you can update your label properly when you came back to this view.

您还应该在视图控制器中保留下面的代码,以便在返回此视图时可以正确更新标签。

-(void)viewDidLoad
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

-(void)aTime
{
    NSLog(@"....Update Function Called....");

    Label.text = [NSString stringWithFormat:@"%d",theSingleton.i];
}

better choice:

更好的选择:

You can declare i as a property of your singleton, and then add an observer to i, then you'll get your label updated on time. call -startTimer when you want to count time.

您可以将 i 声明为您的单身人士的一个属性,然后向 i 添加一个观察者,然后您将及时更新您的标签。当您想计算时间时调用 -startTimer。

the singleton:

单身人士:

  @interface Singleton

  @property (nonatomic,retain) NSNumber *i;

  @end

  @implementation

+(Singleton*)instance
{
    //the singleton code here
}

-(void)startTimer
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

-(void)aTime
{
    NSInteger temp = [i integerValue];
    temp ++;
    self.i = [NSNumber numberWithInteger:temp];
}

the view controller:

视图控制器:

-(void)viewDidLoad
{
    [super viewDidLoad];
    [[Singleton instance] addObserver:self forKeyPath:@"i" options:NSKeyValueObservingOptionNew context:NULL]];
}


- (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary *)change
                   context:(void *)context
{
    NSLog(@"....Update Function Called....");

    Label.text = [NSString stringWithFormat:@"%@",[Singleton instance].i];
}