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

回眸只為那壹抹淺笑 提交于 2019-12-11 00:15:08

问题


I have created an overlay to run while I run an async data grab to the server so that users won't continue pressing buttons in the UI until the data grab is done. I have put the function into a global singleton class and I call it while passing in a bool to say whether or not I want to show or hide. I can get it to show but I cannot get it to hide. Here is the code:

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()
    }

HERE IS WHERE I SET UP THE 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() { }
}

NOW THE EXTENSION WHERE THE MAGIC HAPPENS

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 
    }
}

回答1:


In order to dismiss the UIAlertController (which is a subclass of UIViewController), it should be sufficient to call the dismiss method:

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

It works fine in my sample project.




回答2:


You should do...

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

Hope it helps



来源:https://stackoverflow.com/questions/44728819/ios-10-swift-3-cannot-dismiss-uialertcontroller-from-singleton-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!