NSTimer не работает при перетаскивании UITableView
У меня есть приложение с таймером обратного отсчета. Я сделал это с меткой, которая обновляется с помощью функции, вызванной таймером следующим образом:
...
int timeCount = 300; // Time in seconds
...
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(actualizarTiempo:) userInfo:nil repeats:YES];
...
- (void)actualizaTiempo:(NSTimer *)timer {
timeCount -= 1;
if (timeCount <= 0) {
[timer invalidate];
} else {
[labelTime setText:[self formatTime:timeCount]];
}
}
Примечание: formatTime - это функция, которая получает целое число (количество секунд) и возвращает NSString в формате mm: ss
Все работает нормально, т.е. время отсчитывается, но проблема в том, что у меня есть UITableView в приложении, и если я касаюсь таблицы и перетаскиваю ее (чтобы перемещаться по ячейкам), таймер останавливается, пока я не отпущу палец с экрана...
Это нормальное поведение? Если это так, есть ли способ избежать этого и заставить таймер работать при перетаскивании таблицы?
Ответы
Ответ 1
Используя scheduledTimerWithTimeInterval:
, как говорит j.tom.schroeder, ваш таймер автоматически назначает цикл основного запуска для режимов по умолчанию. Это предотвратит запуск вашего таймера, когда ваш цикл запуска находится в режиме не по умолчанию, например, при нажатии или прокрутке.
Решение, однако, не использует поток, но планирование вашего таймера для всех общих режимов:
NSTimer *timer = [NSTimer timerWithTimeInterval:1
target:self
selector:@selector(actualizarTiempo:)
userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
В зависимости от вида событий, которые вы хотели бы разрешить без остановки своих таймеров, вы также можете рассмотреть UITrackingRunLoopMode
. Дополнительные сведения о режимах цикла запуска см. В Apple Docs.
Ответ 2
Вот версия Swift:
Swift 2
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "removeFromSuperview", userInfo: nil, repeats: false)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
Свифт 3, 4, 5
var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(removeFromSuperview), userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
Ответ 3
Это нормальное поведение. scheduledTimerWithTimeInterval:
в текущем цикле выполнения, поэтому любое взаимодействие с UITableView блокирует вызов метода actualizarTiempo:
. Используйте методы NSThread detachNewThreadSelector:toTarget:withObject
и sleepForTimeInterval
для выполнения actualizarTiempo:
в отдельном потоке.
Ответ 4
Swift версия 4+:
var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.TimerController), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
если вы хотите повторить, например, как счетчик, тогда установите repeat = true, иначе = false