如何同步UIAlertController的结果?

时间:2017-04-24 10:29:12

标签: ios swift grand-central-dispatch uialertcontroller

我正在尝试实现UINavigationBarDelegate,我想显示一条警告,让用户确定是否离开此视图。

这是我的代码:

extension CDFFormController: UINavigationBarDelegate {

    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        if let entityViewController = self.topViewController as? MyEntityViewController {
            if entityViewController.isEditing {
                let semaphore = DispatchSemaphore(value: 0)
                var result = false
                let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
                    result = true
                    semaphore.signal()
                }))
                alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { _ in
                    semaphore.signal()
                }))
                entityViewController.present(alert, animated: true, completion: nil)

                semaphore.wait()
                return result
            } else {
                return true
            }
        } else {
            return true
        }

    }

}

我需要返回结果,所以我使用DispatchSemaphore来阻止该方法。但问题是:在主队列上调用此方法,阻塞它意味着阻止ui线程,方法永远不会返回。

或其他任何解决方案?

1 个答案:

答案 0 :(得分:0)

我不确定它会起作用。我没试过这个。

extension CDFFormController: UINavigationBarDelegate {

public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
    if let entityViewController = self.topViewController as? MyEntityViewController {
        if entityViewController.isEditing {
            let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
                let saveDelegate = navigationBar.delegate;
                navigationBar.delegate = nil;
                navigationBar.popItem(animated:YES);
                navigationBar.delegate = saveDelegate;
            }))
            alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler:nil))
            entityViewController.present(alert, animated: true, completion: nil)


            return false
        } else {
            return true
        }
    } else {
        return true
    }

}

}

其他方式是使用RunLoop。但我不喜欢这样。

extension CDFFormController: UINavigationBarDelegate {

    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        if let entityViewController = self.topViewController as? MyEntityViewController {
            if entityViewController.isEditing {
                let state = 0
                var result = false
                let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
                    state = 1

                }))
                alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { _ in
                    state = 2
                }))
                entityViewController.present(alert, animated: true, completion: nil)

                while (state == 0)
                {
                   RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.5))
                }
                return state == 1
            } else {
                return true
            }
        } else {
            return true
        }

    }

}