如何确保performSegueWithIdentifier()只执行一次?

时间:2016-03-15 20:21:25

标签: ios swift

当点击按钮时,我执行网络调用并成功响应时执行performSegueWithIdentifier()以导航到下一个视图控制器。但有时用户会多次点按该按钮,因为在从网络获得响应之前可能会有延迟。

如何确保performSegueWithIdentifier()只执行一次?

或者,在从网络接收响应之前,是否有更好的方法来禁用用户界面?

...我尝试使用presentedViewControllerpresentingViewController识别“当前”视图控制器,但看起来我的理解是错误的,因为我无法使用它

这是我创建的一个片段,用于隔离和复制问题(我的视图控制器嵌入在导航控制器中):

// MARK: - Actions
@IBAction func buttonPressed(sender: AnyObject) {
    delay(3.0) {
        self.performSegueWithIdentifier("seg", sender: nil)
    }
    self.performSegueWithIdentifier("seg", sender: nil)
}

// MARK: - Helper
func delay(delay: Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

2 个答案:

答案 0 :(得分:2)

您可以禁用该按钮,但竞争条件仍然存在。你需要的是你可以在第一次设置的bool属性。然后你只需在方法的顶部添加一个“if(alreadyPressed_)return”。当然,你必须在按下按钮时设置它,你必须弄清楚什么时候可以安全地清除按钮再次按下按钮。

答案 1 :(得分:0)

以下代码段可用作参考。您可以根据需要多次按下按钮,但延迟后,segue只会执行一次。 delay()功能只是为了模拟在问题中描述的网络呼叫等待完成。

var loginInProgress = false

@IBAction func buttonPressed(sender: AnyObject) {
    guard !loginInProgress else { return }
    loginInProgress = true
    delay(3.0) {
        self.performSegueWithIdentifier("seg", sender: nil)
        self.loginInProgress = false
    }
}


// MARK: - Helper
func delay(delay: Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}