Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 计时器从不在我的平移手势回调函数中触发_Ios_Swift_Timer_Uipangesturerecognizer_Runloop - Fatal编程技术网

Ios 计时器从不在我的平移手势回调函数中触发

Ios 计时器从不在我的平移手势回调函数中触发,ios,swift,timer,uipangesturerecognizer,runloop,Ios,Swift,Timer,Uipangesturerecognizer,Runloop,我尝试仅在用户开始平移0.3秒时显示按钮,以避免在某些情况下(例如,如果手指未一起抬起,则在缩放结束时)立即显示按钮。为了实现这一点,我在平移手势处于.start状态时启动一个计时器,然后仅当计时器变为nil时才在.changed状态下显示按钮 然而,直到我举起我的手指,即手势结束,我的计时器才开始运行。我想这可能与运行循环和占用主线程的手势有关?任何解决办法都将不胜感激。谢谢 var timer: Timer? func handler(_ sender: UIPanGestureRecog

我尝试仅在用户开始平移0.3秒时显示按钮,以避免在某些情况下(例如,如果手指未一起抬起,则在缩放结束时)立即显示按钮。为了实现这一点,我在平移手势处于.start状态时启动一个计时器,然后仅当计时器变为nil时才在.changed状态下显示按钮

然而,直到我举起我的手指,即手势结束,我的计时器才开始运行。我想这可能与运行循环和占用主线程的手势有关?任何解决办法都将不胜感激。谢谢

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
    }
}
试试这个:

    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
        }
    }

如果您的主要目标是在用户开始平移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
    }
}

执行块中没有代码;你故意忽略了这个吗?不,我只是想让计时器在触发后使自己失效,所以我不想让它执行任何事情。嗯,使计时器失效只会将其从运行循环中移除。creating类仍然持有对它的引用,因此它本身不会变成nil。如果你死心塌地想这样做,那么在var timer:timer?前面加上weak,明白了,但是你的解决方案仍然不能解决这个问题,即在平移手势结束之前,定时器永远不会运行