UIScrollView在滚动时会暂停NSTimer

7
我有一个 UIScrollView,里面有一系列正在快速更新数字(每 0.06 秒)的标签。然而,在滚动视图移动时,NSTimer 会暂停,并且直到滚动和弹性动画完成后才继续运行。
我该如何避免这种情况,让 NSTimer 不受滚动视图状态影响而始终运行?
3个回答

25

解决这个问题的简单方法是将你的 NSTimer 添加到 mainRunLoop 中。

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

要从所有运行循环模式中删除已安装的计时器,请向计时器发送 invalidate消息。


那么,这样我实际上不需要启动计时器,它会在执行该行时自动启动,对吗? - Peter Kazazes
从文档中得知:"您可以将计时器添加到多个输入模式中。在指定模式下运行时,接收器会在其预定的触发日期之前或之后引发计时器。触发后,计时器调用其关联的处理程序例程,该例程是指定对象上的选择器。" - Iñigo Beitia

1

对于Swift:

NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)

RunLoop.main.add(timer, forMode: RunLoop.Mode.common) - tyler

0

(Swift) 另一种选择:您可以使用基于GCD的计时器系统,例如以下示例:

class GCDTimer {

    private var _timer : dispatch_source_t?

    init() {

    }

    private func _createTheTimer(interval : Double, queue : dispatch_queue_t, block : (() -> Void)) -> dispatch_source_t
    {
        let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        if (timer != nil)
        {
            dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, Int64(interval * Double(NSEC_PER_SEC))), UInt64(interval * Double(NSEC_PER_SEC)), (1 * NSEC_PER_SEC) / 10);
            dispatch_source_set_event_handler(timer, block);
            dispatch_resume(timer);
        }
        return timer;
    }


    func start(interval : Double, block : (() -> Void))
    {
        let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        _timer = _createTheTimer(interval, queue: queue, block: block)

    }

    func stop()
    {
        if (_timer != nil) {
            dispatch_source_cancel(_timer!);
            _timer = nil;
        }
    }
}

以下是如何使用它的示例代码:`var myInterval:GCDTimer = GCDTimer() myInterval.start(1.0) { println("lol") }` - Thyselius
如果您想使用此计时器更新UI元素,则必须在主线程上执行此操作,如下所示:dispatch_async(dispatch_get_main_queue(),{ self.myUIImageView.image = UIImage(data:data as!NSData)! }) - Thyselius
很高兴你觉得它有用! - raf

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