Таймер никогда не срабатывает в моей функции обратного вызова жестом панорамирования

Я пытаюсь показать кнопку только тогда, когда пользователь начинает панорамирование в течение 0,3 секунды, чтобы в некоторых случаях не показывать кнопку мгновенно (например, в конце увеличения, если пальцы не подняты вместе). Чтобы добиться этого, я запускаю таймер, когда жест панорамирования находится в .began состояние, затем показывает кнопку в .changed состояние только когда таймер становится нулевым.

Тем не менее, мой таймер никогда не работает, пока я не подниму палец (то есть жест .ended). Я полагал, что это, вероятно, связано с циклом выполнения и жестом, занимающим основной поток? Любой обходной путь будет оценен. Спасибо!

var timer: Timer?

func handler(_ sender: UIPanGestureRecognizer) {
    switch sender.state {
    case .began:
        if timer == nil {
            // I just want timer to invalidate itself after firing, so nothing to execute
            self.timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { _ in })
    case .changed:
        if button.isHidden && timer == nil {
            button.isHidden = false
        }
    case .ended:
        button.isHidden = true
        timer?.invalidate()
        timer = nil
    default:
        return
    }
}

2 ответа

Если ваша основная цель - просто показать кнопку ПОСЛЕ того, как пользователь начинает панорамирование в течение 0,3 секунды, все, что вам нужно сделать, это определить, когда перемещен жест панорамирования, а затем показать кнопку. Вам даже не нужно создавать таймер на жесте начала.

var timer: Timer?

func handler(_ sender: UIPanGestureRecognizer) {

    switch sender.state {
    case .changed:
        if (timer == nil || timer?.isValid == false) {
            timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false) { (_) in
                // Show button
                self.button.isHidden = false
            }
        }
    case .ended :
        button.isHidden = true
        timer?.invalidate()
    default:
        return
    }
}

Попробуй это:

    var timer: Timer?

    func handler(_ sender: UIPanGestureRecognizer) {
        switch sender.state {
        case .began:
            if timer == nil {
                self.timer = Timer.scheduledTimer(
                withTimeInterval: 0.3, 
                repeats: false, 
                block: { [weak self] _ in
                   self?.button.isHidden = false 
                })
        case canceled, .ended:
            timer?.invalidate()
            timer = nil
        default:
            return
        }
    }
Другие вопросы по тегам