Обновление UILabel прекращается во время прокрутки UIScrollView
У меня есть scrollView с изображением внутри. scrollView
- это subView супервизора, а imageView - это subView scrollView
.
У меня также есть метка (на уровне супер-просмотра), которая получает обновленные значения по свойству текста из NSTimer каждые миллисекунды.
Проблема заключается в следующем:
Во время прокрутки метка перестает отображать обновления. Когда прокрутка заканчивается, обновления перезапуска метки. При обновлении обновлений они верны; это означает, что значения label.text обновляются так, как ожидалось, но при прокрутке дисплей обновлений иногда переоценивается.
Я хотел бы показывать обновления на ярлыке независимо от прокрутки или нет.
Вот как реализованы обновления меток:
- (void)startElapsedTimeTimer {
[self setStartTime:CFAbsoluteTimeGetCurrent()];
NSTimer *elapsedTimeTimer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(updateElapsedTimeLabel) repeats:YES];
}
- (void)updateElapsedTimeLabel {
CFTimeInterval currentTime = CFAbsoluteTimeGetCurrent();
float theTime = currentTime - startTime;
elapsedTimeLabel.text = [NSString stringWithFormat:@"%1.2f sec.", theTime];
}
Спасибо за любую помощь.
Ответы
Ответ 1
У меня была такая же проблема, и я нашел решение здесь: Мои пользовательские элементы пользовательского интерфейса....
Вкратце: пока ваш UIScrollView прокручивается, NSTimer не обновляется, потому что циклы запуска запускаются в другом режиме (NSRunLoopCommonModes, режим, используемый для отслеживания событий).
Решение добавляет ваш таймер к NSRunLoopModes сразу после создания:
NSTimer *elapsedTimeTimer = [NSTimer scheduledTimerWithTimeInterval:0.001
target:self
selector:@selector(updateElapsedTimeLabel)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:elapsedTimeTimer
forMode:NSRunLoopCommonModes];
(Код исходит из сообщения, указанного выше).
Ответ 2
Решение Sergio в Swift 5:
timer = Timer(timeInterval: 1, repeats: true) { [weak self] _ in
self?.updateTimeLabel()
}
RunLoop.current.add(timer, forMode: .common)
Ответ 3
Решение Sergio в Swift 2:
self.updateTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateFunction", userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.updateTimer, forMode: NSRunLoopCommonModes)
Ответ 4
Я видел подобное поведение в сочетании с прокруткой UIScrollView. Вероятно, происходит то, что действие прокрутки полностью блокирует основной цикл цикла, который отвечает за все, что связано с просмотром обновлений. Вы не делаете ничего плохого, обновления в иерархии представлений должны обрабатываться основным циклом, поэтому вы не можете просто обновлять свой UILabel в фоновом потоке (хотя я, вероятно, все же попробую посмотреть, что произойдет).
Я действительно не занимался исследованиями в этой проблеме, но я предполагаю, что вы мало что можете с этим поделать. Я с радостью соглашусь с ответами, которые докажут, что я ошибаюсь!
Ответ 5
Решение Sergio в Swift 3.x:
self.updateTimer = Timer.scheduledTimer(timeInterval:1.0, target: self, selector: "updateFunction", userInfo: nil, repeats: true)
RunLoop.current.add(self.updateTimer, forMode: RunLoopMode.commonModes)