Подтвердить что ты не робот

IOS: выполнение действия после времени, когда пользователь взаимодействует/прокручивается

Я пытаюсь заставить мое приложение выполнить действие после задержки, но это нужно сделать, если пользователь взаимодействует с/прокруткой на UIScrollView.

Я не уверен, почему не срабатывают ни performSelector:withObject:afterDelay, ни scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:. Это потому, что они находятся в фоновом потоке?

Любые предложения или помощь?

4b9b3361

Ответ 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])