【问题标题】:Triggering a redisplay upon date change在日期更改时触发重新显示
【发布时间】:2012-07-06 17:20:18
【问题描述】:

这可能是一个简单的问题,但我是新手,所以我在画一个空白。

我有一个 2D 图形应用程序,其图形(在 drawRect 中实现)取决于日期。当日期改变时,图形改变,所以我想我需要调用

[myView setNeedsDisplay: YES];

日期更改时。我看过计时器的代码,但这似乎不是计时器类型的场景。我将如何检查本地日期是否已更改,以及将该代码放入哪个类?我认为它会放在 .m 文件中作为我的主视图。

除了在日期更改时自动触发之外,最终,应用程序还需要在用户输入时触发(可能是某一天前进或后退的按钮或日期选择器选择时)。

图形渲染得很好,但我没有编写任何日期触发器,因此虽然 drawRect 代码是特定于日期的,但它不会在日期更改时更改。

附:上面我的基本问题已经得到解答,但是现在我去实现它,我意识到我还有另一个问题。我应该在某处有一个属性来跟踪当前显示其配置的日期。显而易见的想法是向持有 NSDate 对象的主视图添加一个属性。但是按照我编写代码的方式,计算是通过子视图类中的方法完成的。那么问题来了,如何从子视图更新主视图的 NSDate 属性。另一种方法是将 NSDate 属性添加到子视图,但是有多个这样的子视图,这似乎是多余的。对此有何看法?

【问题讨论】:

  • 我什么都没试过。在尝试某事之前,我需要先有一个想法,出于某种原因,我正在画一个空白。我将研究 NSDate 和相关项目。谢谢。
  • 另外,您应该更具体地了解您想要什么样的日期更改 - 日、年、月、分、秒? NSDate 将注册所有这些更改,您可以自行隔离所需的更改。
  • Dustin,如果日期变化的类型不同,真的会改变答案吗?无论如何,没有更多细节,日期只是一天的名称。日期每天都在变化。我希望参与的活动是日常活动。不过,一般来说,它不需要。默认情况可能会在当地时间午夜触发,但同样不必如此。例如,对于测试,我可能会使用分钟触发器。

标签: objective-c date graphics drawrect setneedsdisplay


【解决方案1】:

您可以为此使用NSTimer。不过,首先,您需要弄清楚NSTimer 应该何时触发。为此,您可以使用NSDateNSCalendarNSDateComponents

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *todayComponents = [calendar components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
NSDate *today = [calendar dateFromComponents:todayComponents];
// today is the start of today in the local time zone.  Note that `NSLog`
// will print it in UTC, so it will only print as midnight if your local
// time zone is UTC.

NSDateComponents *oneDay = [[NSDateComponents alloc] init];
oneDay.day = 1;
NSDate *tomorrow = [calendar dateByAddingComponents:oneDay toDate:today options:0];

拥有tomorrow 后,您可以设置在该日期触发的计时器:

NSTimer *timer = [[NSTimer alloc] initWithFireDate:tomorrow interval:0 target:self selector:@selector(tomorrowTimerDidFire:) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
// The run loop retains timer, so you don't need to.

tomorrowTimerDidFire::

- (void)tomorrowTimerDidFire:(NSTimer *)timer {
    [myView setNeedsDisplay:YES];
}

【讨论】:

  • 非常感谢您的详尽回复。
  • 我忘了提到你可能想在tomorrowTimerDidFire: 中创建另一个计时器,因为当tomorrowTimerDidFire: 运行时,旧的明天就是今天,你需要在新的明天再次调用它.
  • 谢谢,罗伯。这就是我的假设,但提到它是个好主意。这就引出了另一个问题。在我阅读计时器时,我看到提到在完成时杀死计时器。愿意对此发表评论吗?
  • 非重复计时器会自动使其自身失效。您无需进行任何其他清理工作。
  • 好。现在我坐下来解决这个问题,我意识到我还有另一个问题。但也许它需要自己的问题。我真的应该将日期存储在某个地方。我认为主视图是最好的地方,但日期计算实际上是在子视图中完成的。我可以在子视图的主视图中设置日期属性吗?我可以在子视图中设置一个属性,但是有很多,这似乎是多余的。我会更具体,但我的字符用完了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多