检查一个视图自午夜以来是否已经加载

5
我有一个ViewController,它对数组执行随机洗牌并将文本输出到标签(在viewDidLoad方法中)。问题是,每当我导航到同一个ViewController时,它就会再次执行洗牌,而我只需要它每天洗牌一次。
因此,我需要检查此ViewController是否在同一天(即从午夜开始)被加载过,然后我可以将洗牌放入if语句中。我能否在午夜安排洗牌,而不管应用程序是否打开?
我已经研究了将布尔值设置为NSUserDefaults:类似于hasLoadedSinceMidnight,但是无法弄清如何在午夜重置布尔值。

那是一种方法,但您还需要保存您正在“洗牌”的项目的状态,并将其加载。 - Mike D
数组对象来自CoreData,因此它们已经被保存。该方法只是将它们加载到一个数组中,并将它们随机排列到另一个数组中。 - RoshDamunki
2个回答

7

您可以实现AppDelegate的significantTimeChange方法:

-(void)applicationSignificantTimeChange:(UIApplication *)application {
    //tell your view to shuffle
}

这个方法会在每天午夜和重大时间更改(如时区更改)时被调用。如果您的应用程序在事件接收时已关闭,则下次打开应用程序时将调用此方法。

更多信息可以在这里查看。

在ViewController中执行相同操作的另一种方法是添加:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(performAction) name:UIApplicationSignificantTimeChangeNotification object:nil];

然后,您可以在该ViewController的-(void)performAction;方法中执行您的洗牌操作。


1
тюеУДєтЏЙТјДтѕХтЎеСИГУ«бжўЁUIApplicationSignificantTimeChangeNotificationС╗ЦУјитЈќ+1ТѕќТЏ┤тЦйуџёу╝ќуеІСйЊжфїсђѓ - vikingosegundo
没错,我会加上的。 - Jsdodgers
我找不到这个方法触发的重要时间更改的完整列表 - 文档只是说“例如”。如果用户正在乘飞机并移动时区,则可能不适用,除非您可以抑制该方法的一部分。我还看到的另一件事情是它倾向于执行洗牌,但不更新结果文本到UILabel..?无法理解为什么会这样。标签不会更新,因为它的状态已经加载了吗? - RoshDamunki
你是在时间更改方法中手动更改标签吗?通过 label.text = @"SomeText" 进行更改? - Jsdodgers
我不知道那是否是你的确切代码,但看起来你总是得到 objectAtIndex 0,这种情况下文本不会改变,除非你的数组实际上发生了变化。 - Jsdodgers
显示剩余3条评论

0

不要存储一个BOOL,而是可以存储上次洗牌的日期/时间(NSDate)。

然后在viewDidAppear中通过比较存储的日期和当前日期来检查是否已经过了午夜。

请参阅NSTime文档:http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html

以及NSDateFormatter文档: https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003643


更新:

根据要求,这里提供一些示例代码。诚然,可能有更好的解决方案,但我相信这段代码片段将帮助您解决问题。它的作用是检查是否使用NSUserDefaults保存了日期,然后与当前日期进行比较。如果日期不匹配,则对数组进行洗牌,然后保存当前日期(再次使用NSUserDefaults)。 (我假设时间确实会继续向前移动,因此它不会检查lastSavedDate是否在currentDate之前。)

NSDate *currentDate = [[NSDate alloc] init];
NSDate *lastShuffleDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastShuffleDate"];

// check to see if there is a prior shuffle date
// if there is not, shuffle the array and save the current date
if (!lastShuffleDate) {
    NSLog(@"No object set for 'lastShuffleDate'");

    //[self shuffleMyArray];

    [[NSUserDefaults standardUserDefaults] setObject:currentDate forKey:@"lastShuffleDate"];
    return;
}

// set up the date formatter
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
[dateFormatter setLocale:usLocale];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];

NSLog(@"Current Date: %@", [dateFormatter stringFromDate:currentDate]);
NSLog(@"Saved Date: %@", [dateFormatter stringFromDate:lastShuffleDate]);

// check to see if the dates are the same by comparing the dates as a string
if (![[dateFormatter stringFromDate:currentDate] isEqualToString:[dateFormatter stringFromDate:lastShuffleDate]]) {
    NSLog(@"Dates are different...!");

    //[self shuffleMyArray];

} else {
    NSLog(@"Dates are the same... (midnight has not passed)");
}

// save the time of the last shuffle
[[NSUserDefaults standardUserDefaults] setObject:currentDate forKey:@"lastShuffleDate"];

目前为止,你没有真正的理由去检查时间,但我包含了它以防你好奇。

// remote dateStyle and set timeStyle to check times
[dateFormatter setDateStyle:NSDateFormatterNoStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"Current Time: %@", [dateFormatter stringFromDate:currentDate]);
NSLog(@"Saved Time: %@", [dateFormatter stringFromDate:lastShuffleDate]);

有趣 - 所以在视图加载时创建一个时间戳并将其保存到NSUserDefaults?还是只在视图内执行检查方法? - RoshDamunki
当你洗牌时,将时间存储在NSUserDefaults中。在viewDidAppear(可能是您需要的更好选项)中,检查当前时间与NSUserDefaults中保存的时间,并确定午夜是否已过。如果是,则重新洗牌并使用当前时间更新NSUserDefaults以反映最后一次洗牌。 - rog
你能给我一些示例代码吗?我已经尝试过让它工作,但似乎无法实现。timeIntervalSinceNow返回两个日期之间的秒数。如果用户在23:45打开应用程序,然后在00:01再次打开,只有16分钟(960秒)过去了。因此,<86400秒已经过去,但是已经到了第二天。使用两个日期的NSDayCalendarUnit进行比较是否有效?(如果它们不相等,则洗牌) - RoshDamunki
@RoshDamunki 我已经更新了我的初始答案并添加了一些代码。希望这可以帮到你。如果可以的话,请将其标记为正确答案以完成问题。 - rog
1
非常抱歉耽搁了 - 由于硬盘严重崩溃,目前正在整理中。代码看起来不错,但我会在明天测试我的另一台机器上。我可能会将 NSLocale 更改为 currentLocale...并且同意 - 据我所知,时间倒流是不可能的...否则我现在就要更换硬盘了....! - RoshDamunki
不需要道歉。是的,使用任何所需的Locale。我只是选择了这个,因为我住在美国。话虽如此,我的建议会起作用,但你应该考虑查看上面Jsdodgers的建议。 - rog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接