ios 10+,Swift 3+ - 无法从 Singleton 实例中关闭 UIAlertController

ios 10+, Swift 3+ - Cannot dismiss UIAlertController from Singleton instance

我在 运行 上创建了一个叠加层,同时我 运行 将异步数据抓取到服务器,这样用户就不会继续按下 UI 中的按钮,直到数据抓取已经完成了。我已将该函数放入全局单例 class 中,并在传入布尔值时调用它来说明我是想显示还是隐藏。我可以让它显示,但我无法让它隐藏。这是代码:

class DataModel {
    static let sharedInstance = DataModel()
    func accessNetworkData(vc: UIViewController, params: [String:Any], wsURLPath: String, completion: @escaping (_ response: AnyObject) -> ()) {
        DataModel.sharedInstance.toggleModalProgess(show: true)
        // SHOW THE MODAL HERE ONCE THE DATA IS REQUESTED.
        let url = URL(string: wsURLPath)!
        let session = URLSession.shared
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        do { request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted) } catch let error { print(error.localizedDescription) }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            DataModel.sharedInstance.toggleModalProgess(show: false)
            // NOW SINCE THE NETWORK ACTIVITY IS DONE, HIDE THE UIALERTCONTROLLER
            guard error == nil else {
                print("WEB SERVICE ERROR <----------------------------<<<<<< " + wsURLPath)
                print(error!)
                let resp: [String: String] = [ "conn": "failed" ]

                DispatchQueue.main.async { completion(resp as NSDictionary) }
                return
            }
            guard let data = data else {
                print("WEB SERVICE ERROR <----------------------------<<<<<< " + wsURLPath)
                return
            }
            do {
                if let parsedJSON = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                    print("WEB SERVICE SUCCESS <----------------------------<<<<<< "+wsURLPath+" "+String(describing:params))
                    if let parsedResponseDict = parsedJSON["d"] as? NSDictionary {
                        DispatchQueue.main.async {
                            completion(parsedResponseDict)
                        }
                    }else if let parsedResponseArr = parsedJSON["d"] as? NSArray {
                        DispatchQueue.main.async {
                            completion(parsedResponseArr)
                        }
                    }else {
                        print("INVALID KEY <----------------------------<<<<<< " + wsURLPath)
                        DispatchQueue.main.async {
                            completion(parsedJSON as AnyObject)
                        }
                    }
                }
            } catch let error {
                print("Error with JSON Serialization")
                print(error.localizedDescription)
            }
        })
        task.resume()
    }

这里是我设置 UIALERTCONTROLLER

的地方
    let modalAlert = UIAlertController(title: "Please Wait...", message: "Loading Data...", preferredStyle: UIAlertControllerStyle.alert)
    let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))

    func toggleModalProgess(show: Bool) -> Void {
        print("toggleModalProgess: show = " + String(describing: show))
        if (show) {
            print("let's turn it on")
            loadingIndicator.hidesWhenStopped = true
            loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
            loadingIndicator.startAnimating()
            modalAlert.view.addSubview(loadingIndicator)
            modalAlert.show()
        }else {
            print("let's turn it off")
            modalAlert.hide()
        }
    }

    private init() { }
}

现在是奇迹发生的扩展

public extension UIAlertController {
    func show() {
        let win = UIWindow(frame: UIScreen.main.bounds)
        let vc = UIViewController()
        vc.view.backgroundColor = .clear
        win.rootViewController = vc
        win.windowLevel = UIWindowLevelAlert + 1
        win.makeKeyAndVisible()
        vc.present(self, animated: true, completion: nil)
    }
    func hide() {
        // HERE IS WHERE I NEED TO HIDE IT BUT I AM HAVING ISSUES 
    }
}

为了关闭UIAlertController(它是UIViewController的子类),调用dismiss方法应该就足够了:

func hide() {
    dismiss(animated: true, completion: nil)
}

它在我的示例项目中运行良好。

你应该做...

self.presentingViewController?.dismiss(animated: true, completion: nil)

希望对您有所帮助