2

我将 NSTimer 用于我的 iOS 应用程序,但由于 SetNeedsDisplay,我没有得到我想要的结果。

我做了一些研究,发现 CADisplayLink 给了我想要的动画结果。遗憾的是,我无法像使用 NSTimer 那样设置计时器。

[NSTimer scheduledTimerWithTimeInterval:0.250 target:self selector:@selector(setGaugeLevel) userInfo:nil repeats:YES];

我的 CADisplayLink 调用我的函数太快了,我想给它与我使用 NSTimer 时相同的计时器(0.250 秒)。

CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(setGaugeLevel)];
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

setGaugeLevel 函数内部只有一个循环,其中包含一个 SetValue 函数,在每次迭代中包含:

[self setNeedsDisplay];

有什么办法可以减慢速度以获得我想要的结果?

4

2 回答 2

4

正如@carton 所指出的,CADisplayLink用于使您自己与显示器同步。它不是通用计时器。它特别适用于您希望以与同步刷新相关的方式进行更新的实时视频等情况。这显然不是你的问题。

您描述的方法没有多大意义。调用setNeedsDisplay不会导致视图立即重绘。它只是将其标记为在下一个绘图周期重新绘制。setNeedsDisplay循环调用是没有意义的。setGaugeLevel必须返回,否则视图将永远不会更新(因为您将挂起 UI 队列)。

如果您只想让进度表以 0.25 秒的增量上升,那么只需增加进度指示器的值并返回。用NSTimer. 当它达到 100% 时,使计时器无效,使其停止。

你甚至不需要打电话setNeedsDisplay。进度指示器知道当它们的值发生变化时需要重新绘制它们。

于 2015-12-30T20:33:43.623 回答
3

CADisplayLink与显示刷新率有关,它(通常?)以 60Hz 运行,即每秒 60 帧。您无法控制它触发的时间间隔,但它有一个设置 a 的选项frameInterval,允许您指定“在显示链接再次通知目标之前必须通过的帧数”。

在您的代码中,添加一行以将更新限制为大约每 0.25 秒一次:

CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(setGaugeLevel)];
displayLink.frameInterval = 15 // 0.25s, assuming 60Hz display refresh rate
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

但是,如果您需要精确计时而不锁定显示刷新率,那么您最好的方法可能仍然是NSTimer. 你遇到了什么问题?

于 2015-12-30T20:16:26.227 回答