【问题标题】:Checking the current view state after block/closure completion块/关闭完成后检查当前视图状态
【发布时间】:2016-04-12 21:20:10
【问题描述】:

在异步执行的块/闭包中,我想在执行该块中的任何内容之前检查我的当前状态。

一个常见的例子是在 NSURLsession 请求之后继续到下一个视图控制器。

这是一个例子:

@IBAction func tappedButton(sender: UIButton) {

    //This closure named fetchHistorical goes to the internet and fetches an array 
    //The response is then sent to the next view controller along with a segue

    Order.fetchHistorical(orderID, completionHandler: { (resultEnum) -> () in
            switch resultEnum {
            case .Success(let result):
                let orderItemsArray = result.orderItems!.allObjects
                self.performSegueWithIdentifier("showExchanges", sender: orderItemsArray)

            default:
                let _ = errorModal(title: "Error", message: "Failed!")
            }
    })
}

假设用户不耐烦并点击了此按钮 3 次。

这意味着该函数将被调用 3 次,并且每次它都会尝试转到下一个视图控制器(iOS 很好地通过“警告:尝试在其上显示不在窗口层次结构中的视图!”来阻止这个问题! )

我想知道你们是如何解决这个问题的?是否类似于...在闭包中,检查您是否仍在当前的视图控制器中...如果您在,那么 segueing 是有效的。如果没有,您可能已经转场并且不再执行转场。

***更一般地说,由于闭包是异步执行的,您如何检查闭包中的当前状态?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    由于闭包不在主线程上执行,因此如果您在此处检查它(如您所述),状态将是准确的。您可以使用 GCD 转到主线程并检查那里的状态。有几种方法可以防止此代码多次运行。如果执行计算需要一些时间,您可以使用活动指示器让用户知道应用程序目前很忙。如果您希望用户仍然可以选择按下按钮,您可以添加如下标签:

    var buttonWasTapped:Bool = false //class property
    @IBAction func tappedButton(sender: UIButton) {
       if !self.buttonWasTapped{
            self.buttonWasTapped = true
        }
    }
    

    然后在 viewDidAppear 上将其改回 false,这样他们每次显示该页面时都可以按一次。

    【讨论】:

      【解决方案2】:

      当开始一些需要一些时间才能完成的任务时,我会做两件事;

      1. 显示某种活动指示器,以便用户知道正在发生的事情
      2. 禁用该按钮,以便进一步指示已收到请求并防止用户多次点击。

      重要的是,您不仅要考虑应用的正确操作,还要考虑提供良好的用户体验。

      【讨论】:

        猜你喜欢
        • 2018-05-18
        • 2014-04-10
        • 2019-08-06
        • 2019-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-20
        相关资源
        最近更新 更多