IOS: выполнение действия после времени, когда пользователь взаимодействует/прокручивается
Я пытаюсь заставить мое приложение выполнить действие после задержки, но это нужно сделать, если пользователь взаимодействует с/прокруткой на UIScrollView
.
Я не уверен, почему не срабатывают ни performSelector:withObject:afterDelay
, ни scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
. Это потому, что они находятся в фоновом потоке?
Любые предложения или помощь?
Ответы
Ответ 1
Оба NSTimer
и performSelector:withObject:afterDelay:
по умолчанию запускают только огонь в обычном режиме цикла. При прокрутке цикл запуска находится в режиме отслеживания событий.
Вы должны запланировать время выполнения во всех общих режимах:
NSTimer *timer = [NSTimer timerWithTimeInterval:0.016 target:self selector:@selector(fire:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
или
[self performSelector:@selector(fire:) withObject:nil afterDelay:1.0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
Там также выделен NSEventTrackingRunLoopMode
.
Ответ 2
Убедитесь, что срабатывание с задержкой происходит на NSRunLoopCommonModes
. По умолчанию используется NSDefaultRunLoopMode
, который не будет получать сообщения, например. скроллинг.
[self performSelector:@selector(fire:) withObject:nil afterDelay:2.0 inModes:@[NSRunLoopCommonModes]];
В качестве альтернативы вы можете использовать GCD
, который также ведет себя одинаково (не уверен, какой режим runloop он использует)
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
<#code to be executed on the main queue after delay#>
});
Ответ 3
Для Swift:
performSelector(#selector(fire:), withObject: sender, afterDelay: 1.0, inModes: [NSRunLoopCommonModes])