我在iOS应用程序中使用NSTimer,但由于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];
有没有办法放慢速度以得到我想要的结果?
正如@carton所指出的,CADisplayLink
用于将您自己与显示器同步。它不是一个通用计时器。它专门用于实时视频等情况,您希望以与同步刷新相关的方式进行更新。这显然不是你的问题。
你所描述的方法没有多大意义。调用setNeedsDisplay
不会导致视图立即重新绘制。它只是将其标记为在下一个绘图周期重新绘制。在循环中调用setNeedsDisplay
是没有意义的。setGaugeLevel
必须返回,否则视图将永远不会更新(因为您将挂起UI队列)。
如果你只想让进度表以.25s的增量上升,那么只需增加进度指示器的值并返回。用NSTimer
来称呼它。当它达到100%时,使计时器无效,使其停止。
你甚至不应该打电话给setNeedsDisplay
。进度指标知道,当其值发生变化时,需要重新绘制进度指标。
CADisplayLink
链接到显示器刷新率,它(通常?)以60Hz运行,即每秒60帧。您无法控制它触发的时间间隔,但它可以选择设置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
。你遇到了什么问题?