当点击按钮时,我执行网络调用并成功响应时执行performSegueWithIdentifier()以导航到下一个视图控制器。但有时用户会多次点按该按钮,因为在从网络获得响应之前可能会有延迟。
如何确保performSegueWithIdentifier()只执行一次?
或者,在从网络接收响应之前,是否有更好的方法来禁用用户界面?
...我尝试使用presentedViewController
和presentingViewController
识别“当前”视图控制器,但看起来我的理解是错误的,因为我无法使用它
这是我创建的一个片段,用于隔离和复制问题(我的视图控制器嵌入在导航控制器中):
// 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)
}
答案 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)
}