Замедление интервала CADisplayLink

Я использовал 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];

Есть ли способ замедлить его, чтобы получить желаемый результат?

2 ответа

Как отмечает @carton, CADisplayLink для синхронизации себя с дисплеем. Это не общий таймер. Это специально для случаев, таких как видео в реальном времени, где вы хотите обновить таким образом, который связан с обновлением синхронизации. Это явно не ваша проблема здесь.

Ваш метод, как вы описываете, не имеет большого смысла. призвание setNeedsDisplay не заставляет представление немедленно перерисовать. Он просто помечает его для перерисовки на следующем цикле рисования. Никогда не имеет смысла звонить setNeedsDisplay в петле. setGaugeLevel должен вернуться или там представление никогда не будет обновлено (потому что вы повесите очередь пользовательского интерфейса).

Если вы просто хотите, чтобы индикатор прогресса увеличивался с шагом в 25 с, просто увеличьте значение индикатора прогресса и верните его. Назовите это с NSTimer, Когда он достигнет 100%, отключите таймер, чтобы он остановился.

Вам даже не нужно звонить setNeedsDisplay, Индикаторы прогресса знают, что их нужно перерисовывать при изменении их значения.

CADisplayLink связан с частотой обновления дисплея, он (как правило?) работает на частоте 60 Гц, то есть 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, С какими проблемами вы сталкиваетесь?

Другие вопросы по тегам