Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift UIAlertController已显示(空)_Swift_Uialertcontroller - Fatal编程技术网

Swift UIAlertController已显示(空)

Swift UIAlertController已显示(空),swift,uialertcontroller,Swift,Uialertcontroller,我有一个应用程序,一开始会显示一张地图,上面有所有靠近我位置的公司。主屏幕上有一个搜索按钮,我可以在这里单击并根据我的具体需要过滤结果 Mapa View Controller和Filtrar View Controller之间的连接是基于自定义协议建立的(根据) 所有的沟通都很好,我能够筛选和展示符合标准的公司。我的问题是当过滤器不返回任何内容时(没有符合条件的公司)。当这种情况发生时,我想向最终用户提供一个UIAlter作为建议 警报已触发,但我收到一条错误消息“尝试呈现已呈现的内容(空)

我有一个应用程序,一开始会显示一张地图,上面有所有靠近我位置的公司。主屏幕上有一个搜索按钮,我可以在这里单击并根据我的具体需要过滤结果

Mapa View Controller和Filtrar View Controller之间的连接是基于自定义协议建立的(根据)

所有的沟通都很好,我能够筛选和展示符合标准的公司。我的问题是当过滤器不返回任何内容时(没有符合条件的公司)。当这种情况发生时,我想向最终用户提供一个UIAlter作为建议

警报已触发,但我收到一条错误消息“尝试呈现已呈现的内容(空)”

我试过了我的一个建议

我看到打印的“警报通过另一个呈现的VC出现,例如PopOver”,但我不知道如何使用呈现的VC!。presentViewController(…)

我使用的是XCode 11.2.1和IOS 11

我的详细代码是

警戒级别

import UIKit

class Alerta {
    var titulo : String
    var mensagem : String

    init(titulo: String, mensagem: String) {
        self.titulo = titulo
        self.mensagem = mensagem

    }

    func getAlerta() -> UIAlertController {
        let alerta = UIAlertController(title: titulo, message: mensagem, preferredStyle: .alert)
        let acaoCancelar = UIAlertAction(title: "Ok", style: .cancel, handler: nil)

        alerta.addAction(acaoCancelar)
        return alerta
    }
}
Mapa类

import UIKit
import MapKit
import ProgressHUD

class MapaViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, FiltroVCDelegate {

    @IBOutlet weak var mapa: MKMapView!
    var gerenciadorLocalizacao = CLLocationManager()
    var anotacaoArray = [MinhaAnotacao]()
    // var annotationSearch: [MinhaAnotacao] = [] // Filtered annotation
    var anotacao = MinhaAnotacao()
    var searchArr: [String] = []
    var searching = false

    var todasAnotacoes: [(objLat: CLLocationDegrees, objLong: CLLocationDegrees, objName: String, objDesc: String, objId: String, objTel1: String, objTel2: String, objEsp1: String, objEsp2: String, objEst: String, objCid: String)] = []
    var clinicasR: [(objLat: CLLocationDegrees, objLong: CLLocationDegrees, objName: String, objDesc: String, objId: String, objTel1: String, objTel2: String, objEsp1: String, objEsp2: String, objEst: String, objCid: String)] = []

    @IBOutlet weak var adicionarOutlet: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()

        mapa.register(MyAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)

        // Retrieving Logger user data and hidding "add" button if applicable
        ProgressHUD.show("Carregando...")
        var searching = false


        // Map - User location
        self.mapa.delegate = self
        self.gerenciadorLocalizacao.delegate = self
        self.gerenciadorLocalizacao.desiredAccuracy = kCLLocationAccuracyBest
        self.gerenciadorLocalizacao.requestWhenInUseAuthorization()
        self.gerenciadorLocalizacao.startUpdatingLocation()

        ProgressHUD.dismiss()
    }

    // add annotations to the map
    func addAnnotationsToMap() {
        anotacaoArray = []
        self.mapa.removeAnnotations(mapa.annotations)
        if searching {
            for oneObject in self.clinicasR {
                let umaAnotacao = MinhaAnotacao()
                let oneObjLoc: CLLocationCoordinate2D = CLLocationCoordinate2DMake(oneObject.objLat, oneObject.objLong)
                umaAnotacao.coordinate = oneObjLoc
                umaAnotacao.title = oneObject.objName
                umaAnotacao.subtitle = oneObject.objDesc
                umaAnotacao.identicadorMapa = oneObject.objId
                umaAnotacao.telefone = oneObject.objTel1
                umaAnotacao.telefone2 = oneObject.objTel2
                umaAnotacao.especialidade1 = oneObject.objEsp1
                umaAnotacao.especialidade2 = oneObject.objEsp2
                umaAnotacao.estado = oneObject.objEst
                umaAnotacao.cidade = oneObject.objCid
                umaAnotacao.endereco = oneObject.objDesc
                umaAnotacao.latitude = String(oneObject.objLat)
                umaAnotacao.longitude = String(oneObject.objLong)

                self.anotacaoArray.append(umaAnotacao)
            }

        } else {
            for oneObject in self.todasAnotacoes {
                let umaAnotacao = MinhaAnotacao()
                let oneObjLoc: CLLocationCoordinate2D = CLLocationCoordinate2DMake(oneObject.objLat, oneObject.objLong)
                umaAnotacao.coordinate = oneObjLoc
                umaAnotacao.title = oneObject.objName
                umaAnotacao.subtitle = oneObject.objDesc
                umaAnotacao.identicadorMapa = oneObject.objId
                umaAnotacao.telefone = oneObject.objTel1
                umaAnotacao.telefone2 = oneObject.objTel2
                umaAnotacao.especialidade1 = oneObject.objEsp1
                umaAnotacao.especialidade2 = oneObject.objEsp2
                umaAnotacao.estado = oneObject.objEst
                umaAnotacao.cidade = oneObject.objCid
                umaAnotacao.endereco = oneObject.objDesc
                umaAnotacao.latitude = String(oneObject.objLat)
                umaAnotacao.longitude = String(oneObject.objLong)

                self.anotacaoArray.append(umaAnotacao)
            }
        }
        self.mapa.addAnnotations(self.anotacaoArray)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "clinicaDetailsSegue" {
            let clinicasDetailsViewController = segue.destination as! ClinicasDetailsViewController
            clinicasDetailsViewController.identificador = self.anotacao.identicadorMapa
        } else if segue.identifier == "searchSegue" {
            if let nav = segue.destination as? UINavigationController, let filterVC = nav.topViewController as? FiltrarViewController {
                filterVC.delegate = self
            }
        }
    }

    func search(searchAnnotation: [MinhaAnotacao], searchArr: [String]) -> [MinhaAnotacao] {
        var searchArr = searchArr
        // base case - no more searches - return clinics found
        if searchArr.count == 0 {
            return searchAnnotation
        }
        // itterative case - search clinic with next search term and pass results to next search
        let foundAnnotation = searchAnnotation.filter { item in
            (item.title!.lowercased() as AnyObject).contains(searchArr[0]) ||
                item.especialidade1.lowercased().contains(searchArr[0]) ||
                item.especialidade2.lowercased().contains(searchArr[0]) ||
                item.cidade.lowercased().contains(searchArr[0]) ||
                item.estado.lowercased().contains(searchArr[0]) ||
                item.latitude.contains(searchArr[0]) || item.longitude.contains(searchArr[0]) || item.endereco.contains(searchArr[0])
        }
        // remove completed search and call next search
        searchArr.remove(at: 0)
        return search(searchAnnotation: foundAnnotation, searchArr: searchArr)
    }

    // From Custom Protocol
    func dadosEscolhidos(nomeClinicaFiltro: String, estadoClinicaFiltro: String, cidadeClinicaFiltro: String, especialidade1ClinicaFiltro: String, especialidade2ClinicaFiltro: String) {

        searchArr = []
        clinicasR = []
        searchArr = ["\(nomeClinicaFiltro.lowercased())","\(estadoClinicaFiltro.lowercased())", "\(cidadeClinicaFiltro.lowercased())", "\(especialidade1ClinicaFiltro.lowercased())", "\(especialidade2ClinicaFiltro.lowercased())"]
        searchArr = searchArr.filter({ $0 != ""})

        let annotationSearch = search(searchAnnotation: anotacaoArray, searchArr: searchArr) // Filtered Clinicas

        if annotationSearch.count > 0 {
            for i in 0...annotationSearch.count - 1 {
                self.clinicasR.append((objLat: Double(annotationSearch[i].latitude)!, objLong: Double(annotationSearch[i].longitude)!, objName: annotationSearch[i].title!, objDesc: annotationSearch[i].endereco, objId: annotationSearch[i].identicadorMapa, objTel1: annotationSearch[i].telefone, objTel2: annotationSearch[i].telefone2, objEsp1: annotationSearch[i].especialidade1, objEsp2: annotationSearch[i].especialidade2, objEst: annotationSearch[i].estado, objCid: annotationSearch[i].cidade))
            }

            searching = true
            addAnnotationsToMap()
        } else {

            if self.presentedViewController == nil {
               let alerta = Alerta(titulo: "Erro", mensagem: "Nenhuma clínica atende ao filtro definido")

               self.present(alerta.getAlerta(), animated: true, completion: nil)
               print( "e Aqui, chegou? \(annotationSearch.count)")
            } else {
               // either the Alert is already presented, or any other view controller
               // is active (e.g. a PopOver)
               // ...

               let thePresentedVC : UIViewController? = self.presentedViewController as UIViewController?

               if thePresentedVC != nil {
                  if let thePresentedVCAsAlertController : UIAlertController = thePresentedVC as? UIAlertController {
                     // nothing to do , AlertController already active
                     // ...
                     print("Alert not necessary, already on the screen !")

                  } else {
                     // there is another ViewController presented
                     // but it is not an UIAlertController, so do
                     // your UIAlertController-Presentation with
                     // this (presented) ViewController
                     // ...
                    //let alerta = Alerta(titulo: "Erro", mensagem: "Nenhuma clínica atende ao filtro definido")
                    //thePresentedVC!.presentedViewController(alerta)

                     print("Alert comes up via another presented VC, e.g. a PopOver")
                  }
              }
            }
        }
}
}
过滤器视图控制器

import UIKit
import ProgressHUD

protocol FiltroVCDelegate: class {
    func dadosEscolhidos(nomeClinicaFiltro: String, estadoClinicaFiltro: String, cidadeClinicaFiltro: String, especialidade1ClinicaFiltro: String, especialidade2ClinicaFiltro: String)
}


class FiltrarViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    weak var delegate: FiltroVCDelegate?

    var nomeSelecionado = ""

    var estadosJSON = [Estado]()
    var cidades = [Cidade]()
    var estado : Estado? // Selected State identifier
    var cidade : Cidade? // Selected City identifier
    var estadoSelecionado = "" // Selected State
    var cidadeSelecionada = "" // Selected City

    var especialidadesJSON = [Especialidade]()
    var especialidades2 = [Especialidade2]()
    var especialidade1 : Especialidade? // Selected Specialty1 identifier
    var especialidade2 : Especialidade2? // Selected Specialty2 identifier
    var especialidade1Selecionada = ""
    var especialidade2Selecionada = ""

    let fontName = "HelveticaNeue"
    var searchArr = [String]()

    @IBOutlet weak var nomeClinica: UITextField!
    @IBOutlet weak var especialidadeLabel: UILabel!

    @IBOutlet weak var estadoClinicaPicker: UIPickerView!
    @IBOutlet weak var especialidade1Picker: UIPickerView!
    @IBOutlet weak var especialidade2Picker: UIPickerView!

    override func viewDidLoad() {
        ProgressHUD.show("Carregando...")
        readJsonEstados()
        readJsonEspecialidades()
        super.viewDidLoad()
        nomeClinica.text = ""
        especialidadeLabel.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
        ProgressHUD.dismiss()

    }


    @IBAction func aplicarFiltro(_ sender: Any) {
        if nomeClinica.text == nil {
            nomeClinica.text = ""
        }

        delegate?.dadosEscolhidos(nomeClinicaFiltro: nomeClinica.text!, estadoClinicaFiltro: estadoSelecionado, cidadeClinicaFiltro: cidadeSelecionada, especialidade1ClinicaFiltro: especialidade1Selecionada, especialidade2ClinicaFiltro: especialidade2Selecionada)
        navigationController?.dismiss(animated: true)

    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        especialidade1Picker.reloadComponent(0)
        especialidade2Picker.reloadComponent(0)
        estadoClinicaPicker.reloadAllComponents()

        if pickerView == estadoClinicaPicker {
            if component == 0 {
                self.estado = self.estadosJSON[row]
                self.cidades = self.estadosJSON[row].cidades
                estadoClinicaPicker.reloadComponent(1)
                estadoClinicaPicker.selectRow(0, inComponent: 1, animated: true)
            } else {
                self.cidade = self.cidades[row]
                estadoClinicaPicker.reloadAllComponents()
            }
        } else if pickerView == especialidade1Picker {
            self.especialidade1 = self.especialidadesJSON[row]
            self.especialidades2 = self.especialidadesJSON[row].especialidade2
            especialidade1Picker.reloadComponent(0)
            especialidade2Picker.reloadComponent(0)
            especialidade2Picker.selectRow(0, inComponent: 0, animated: true)

        } else if pickerView == especialidade2Picker {
            self.especialidade2 = self.especialidades2[row]
            especialidade1Picker.reloadComponent(0)
            especialidade2Picker.reloadComponent(0)
        }

        let estadoIndiceSelecionado = estadoClinicaPicker.selectedRow(inComponent: 0)
        let cidadeIndiceSelecionada = estadoClinicaPicker.selectedRow(inComponent: 1)
        let especialidade1IndiceSelecionado = especialidade1Picker.selectedRow(inComponent: 0)
        let especialidade2IndiceSelecionado = especialidade2Picker.selectedRow(inComponent: 0)

        if estadoIndiceSelecionado >= 0 {
            if cidadeIndiceSelecionada >= 0 {
                estadoSelecionado = estadosJSON[estadoIndiceSelecionado].nome
                cidadeSelecionada = cidades[cidadeIndiceSelecionada].nome
            }
        }

        if especialidade1IndiceSelecionado >= 0 {
            if especialidade2IndiceSelecionado >= 0 {
                especialidade1Selecionada = especialidadesJSON[especialidade1IndiceSelecionado].nome
                especialidade2Selecionada = especialidadesJSON[especialidade1IndiceSelecionado].especialidade2[especialidade2IndiceSelecionado].nome
            }
        }
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        if pickerView == estadoClinicaPicker {
            return 2
        } else if pickerView == especialidade1Picker {
            return 1
        } else if pickerView == especialidade2Picker {
            return 1
        }
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if pickerView == estadoClinicaPicker {
            if component == 0 {
                return estadosJSON.count
            } else {
                return cidades.count
            }
        } else if pickerView == especialidade1Picker {
            return self.especialidadesJSON.count

        } else if pickerView == especialidade2Picker {
            return especialidades2.count
        }
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var rowTitle = ""
        let pickerLabel = UILabel()

        pickerLabel.textColor = UIColor.black

        if pickerView == estadoClinicaPicker {
            if component == 0 {
                rowTitle = estadosJSON[row].nome
            } else {
                rowTitle = cidades[row].nome
            }
        } else if pickerView == especialidade1Picker {
            rowTitle = especialidadesJSON[row].nome
        } else if pickerView == especialidade2Picker {
            rowTitle = especialidades2[row].nome
        }

        pickerLabel.text = rowTitle
        pickerLabel.font = UIFont(name: fontName, size: 16.0)
        pickerLabel.textAlignment = .center

        return pickerLabel
    }

    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        if pickerView == estadoClinicaPicker {
            if component == 0 {
                return 50
            } else {
                return 300
            }
        }
        return 300
    }


    @IBAction func cancel(_ sender: Any) {
        navigationController?.dismiss(animated: true)
   }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }

    func readJsonEstados() {
        let url = Bundle.main.url(forResource: "EstadosECidades", withExtension: "json")!
        do {
            let data = try Data(contentsOf: url)
            let jsonResult = try JSONDecoder().decode(RootState.self, from: data)

            //handles the array of countries on your json file.
            self.estadosJSON = jsonResult.estado
            self.cidades = self.estadosJSON.first!.cidades

        } catch {
            let alerta = Alerta(titulo: "Erro ao Carregar", mensagem: "Erro ao carregar Estados e Cidades. Por favor reinicie o app")
            self.present(alerta.getAlerta(), animated: true, completion: nil)
        }
    }

    func readJsonEspecialidades() {
        let url = Bundle.main.url(forResource: "Especialidades", withExtension: "json")!
        do {
            let data = try Data(contentsOf: url)
            let jsonResult = try JSONDecoder().decode(RootEsp.self, from: data)

            //handles the array of specialties on your json file.
            self.especialidadesJSON = jsonResult.especialidade
            self.especialidades2 = self.especialidadesJSON.first!.especialidade2
        } catch {
            let alerta = Alerta(titulo: "Erro ao Carregar", mensagem: "Erro ao carregar Especialidades. Por favor reinicie o app")
            self.present(alerta.getAlerta(), animated: true, completion: nil)
        }
    }

    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destination.
     // Pass the selected object to the new view controller.
     }
     */

}
导入UIKit
导入进度HUD
协议FiltroVCDelegate:类{
func-dadosEscolhidos(nomeClinicaFiltro:String、estadoClinicaFiltro:String、cidadeClinicaFiltro:String、SpecialidadeClinicaFiltro:String、SpecialidadeClinicaFiltro:String)
}
类FiltrarViewController:UIViewController、UIPickerViewDeleteGate、UIPickerViewDataSource{
弱变量委托:FiltroVCDelegate?
var nomeSelecionado=“”
var estadosJSON=[Estado]()
变量cidades=[Cidade]()
var estado:estado?//所选状态标识符
变量cidade:cidade?//所选城市标识符
var estadoSelecionado=”“//所选状态
var cidadeSelecionada=”“//所选城市
var specialidadesjson=[specialidade]()
var specialidades2=[specialidade2]()
var specialidade1:specialidade?//所选Specialty1标识符
var specialidade2:specialidade2?//选择的Specialty2标识符
var specialidade1 selecionada=“”
var specialidade2seleconada=“”
让fontName=“HelveticaNeue”
var searchArr=[String]()
@iba:UITextField!
@IBOutlet弱变量特别是数据标签:UILabel!
@IBV弱var Estadoclinicpicker:UIPickerView!
@IBOutlet弱变量特别是1选择器:UIPickerView!
@IBOutlet弱变量特别是2选择器:UIPickerView!
重写func viewDidLoad(){
ProgressHUD.show(“Carregando…”)
readJsonEstados()
readJsonEspecialidades()
super.viewDidLoad()
nomeClinica.text=“”
specialidadelabel.transform=CGAffineTransform(旋转角度:-CGFloat.pi/2)
ProgressHUD.discover(解雇)
}
@iAction func aplicarFiltro(\发送方:任何){
如果a.text==nil{
nomeClinica.text=“”
}
代表?.dadosEscolhidos(nomeClinicaFiltro:nomeClinica.text!,estadoClinicaFiltro:estadoSelecionado,cidadeClinicaFiltro:cidadeSelecionada,specialidadeclinicafiltro:specialidadeselecionada,specialidadeselecionada)
navigationController?关闭(动画:true)
}
func pickerView(pickerView:UIPickerView,didSelectRow行:Int,不完整组件:Int){
特别是数据1选择器。重新加载组件(0)
特殊数据2选择器。重新加载组件(0)
estadoClinicaPicker.reloadAllComponents()文件
如果pickerView==EstaDoClincipicker{
如果组件==0{
self.estado=self.estadosJSON[row]
self.cidades=self.estadosJSON[row].cidades
EstaDoClincipicker.重新加载组件(1)
EstaDoClincipicker.selectRow(0,不完整:1,动画:true)
}否则{
self.cidade=self.cidades[行]
estadoClinicaPicker.reloadAllComponents()文件
}
}如果pickerView==Specialidade1 Picker,则为else{
self.specialidade1=self.specialidadesjson[row]
self.specialidades2=self.specialidadesjson[row].specialidade2
特别是数据1选择器。重新加载组件(0)
特殊数据2选择器。重新加载组件(0)
特殊数据2选择器。选择行(0,不完整:0,动画:true)
}如果pickerView==SpecialIDADE2Picker,则为else{
self.specialidade2=self.specialidades2[行]
特别是数据1选择器。重新加载组件(0)
特殊数据2选择器。重新加载组件(0)
}
设EstaDoIndiceSelectionAdo=estadoClinicaPicker.selectedRow(不完整项:0)
让cidadeIndiceSelecionada=estadoClinicaPicker.selectedRow(不完整项:1)
让specialidade1indicateselectionado=specialidade1picker.selectedRow(不完整项:0)
让SpecialIDADE2IndicateSelecionado=SpecialIDADE2Picker.selectedRow(不完整项:0)
如果EstadoIndieceselecionado>=0{
如果cidadeIndiceSelecionada>=0{
estadoSelecionado=estadosJSON[estadoIndiceSelecionado].nome
cidadeSelecionada=cidades[cidadesideindiceselecionada].nome
}
}
如果特别指定1指示选择DO>=0{
如果特别指定的2个指标elecionado>=0{
specialidade1selecionada=specialidadesjson[specialidade1indicateselecionado].nome
specialidade2selecionada=specialidadesjson[specialidade1indicateselecionado].specialidade2[specialidade2indicateselecionado].nome
}
}
}
func numberOfComponents(在pickerView:UIPickerView中)->Int{
如果pickerView==EstaDoClincipicker{
返回2
}如果pickerView==Specialidade1 Picker,则为else{
返回1
}如果pickerView==SpecialIDADE2Picker,则为else{
返回1
}
返回1
}
func pickerView(pickerView:UIPickerView,numberOfRowsInComponent:Int)->Int{
如果pickerView==est
import UIKit
import ProgressHUD

protocol FiltroVCDelegate: class {
    func dadosEscolhidos(nomeClinicaFiltro: String, estadoClinicaFiltro: String, cidadeClinicaFiltro: String, especialidade1ClinicaFiltro: String, especialidade2ClinicaFiltro: String)
}


class FiltrarViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    weak var delegate: FiltroVCDelegate?

    var nomeSelecionado = ""

    var estadosJSON = [Estado]()
    var cidades = [Cidade]()
    var estado : Estado? // Selected State identifier
    var cidade : Cidade? // Selected City identifier
    var estadoSelecionado = "" // Selected State
    var cidadeSelecionada = "" // Selected City

    var especialidadesJSON = [Especialidade]()
    var especialidades2 = [Especialidade2]()
    var especialidade1 : Especialidade? // Selected Specialty1 identifier
    var especialidade2 : Especialidade2? // Selected Specialty2 identifier
    var especialidade1Selecionada = ""
    var especialidade2Selecionada = ""

    let fontName = "HelveticaNeue"
    var searchArr = [String]()

    @IBOutlet weak var nomeClinica: UITextField!
    @IBOutlet weak var especialidadeLabel: UILabel!

    @IBOutlet weak var estadoClinicaPicker: UIPickerView!
    @IBOutlet weak var especialidade1Picker: UIPickerView!
    @IBOutlet weak var especialidade2Picker: UIPickerView!

    override func viewDidLoad() {
        ProgressHUD.show("Carregando...")
        readJsonEstados()
        readJsonEspecialidades()
        super.viewDidLoad()
        nomeClinica.text = ""
        especialidadeLabel.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
        ProgressHUD.dismiss()

    }


    @IBAction func aplicarFiltro(_ sender: Any) {
        if nomeClinica.text == nil {
            nomeClinica.text = ""
        }

        delegate?.dadosEscolhidos(nomeClinicaFiltro: nomeClinica.text!, estadoClinicaFiltro: estadoSelecionado, cidadeClinicaFiltro: cidadeSelecionada, especialidade1ClinicaFiltro: especialidade1Selecionada, especialidade2ClinicaFiltro: especialidade2Selecionada)
        navigationController?.dismiss(animated: true)

    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        especialidade1Picker.reloadComponent(0)
        especialidade2Picker.reloadComponent(0)
        estadoClinicaPicker.reloadAllComponents()

        if pickerView == estadoClinicaPicker {
            if component == 0 {
                self.estado = self.estadosJSON[row]
                self.cidades = self.estadosJSON[row].cidades
                estadoClinicaPicker.reloadComponent(1)
                estadoClinicaPicker.selectRow(0, inComponent: 1, animated: true)
            } else {
                self.cidade = self.cidades[row]
                estadoClinicaPicker.reloadAllComponents()
            }
        } else if pickerView == especialidade1Picker {
            self.especialidade1 = self.especialidadesJSON[row]
            self.especialidades2 = self.especialidadesJSON[row].especialidade2
            especialidade1Picker.reloadComponent(0)
            especialidade2Picker.reloadComponent(0)
            especialidade2Picker.selectRow(0, inComponent: 0, animated: true)

        } else if pickerView == especialidade2Picker {
            self.especialidade2 = self.especialidades2[row]
            especialidade1Picker.reloadComponent(0)
            especialidade2Picker.reloadComponent(0)
        }

        let estadoIndiceSelecionado = estadoClinicaPicker.selectedRow(inComponent: 0)
        let cidadeIndiceSelecionada = estadoClinicaPicker.selectedRow(inComponent: 1)
        let especialidade1IndiceSelecionado = especialidade1Picker.selectedRow(inComponent: 0)
        let especialidade2IndiceSelecionado = especialidade2Picker.selectedRow(inComponent: 0)

        if estadoIndiceSelecionado >= 0 {
            if cidadeIndiceSelecionada >= 0 {
                estadoSelecionado = estadosJSON[estadoIndiceSelecionado].nome
                cidadeSelecionada = cidades[cidadeIndiceSelecionada].nome
            }
        }

        if especialidade1IndiceSelecionado >= 0 {
            if especialidade2IndiceSelecionado >= 0 {
                especialidade1Selecionada = especialidadesJSON[especialidade1IndiceSelecionado].nome
                especialidade2Selecionada = especialidadesJSON[especialidade1IndiceSelecionado].especialidade2[especialidade2IndiceSelecionado].nome
            }
        }
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        if pickerView == estadoClinicaPicker {
            return 2
        } else if pickerView == especialidade1Picker {
            return 1
        } else if pickerView == especialidade2Picker {
            return 1
        }
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if pickerView == estadoClinicaPicker {
            if component == 0 {
                return estadosJSON.count
            } else {
                return cidades.count
            }
        } else if pickerView == especialidade1Picker {
            return self.especialidadesJSON.count

        } else if pickerView == especialidade2Picker {
            return especialidades2.count
        }
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var rowTitle = ""
        let pickerLabel = UILabel()

        pickerLabel.textColor = UIColor.black

        if pickerView == estadoClinicaPicker {
            if component == 0 {
                rowTitle = estadosJSON[row].nome
            } else {
                rowTitle = cidades[row].nome
            }
        } else if pickerView == especialidade1Picker {
            rowTitle = especialidadesJSON[row].nome
        } else if pickerView == especialidade2Picker {
            rowTitle = especialidades2[row].nome
        }

        pickerLabel.text = rowTitle
        pickerLabel.font = UIFont(name: fontName, size: 16.0)
        pickerLabel.textAlignment = .center

        return pickerLabel
    }

    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        if pickerView == estadoClinicaPicker {
            if component == 0 {
                return 50
            } else {
                return 300
            }
        }
        return 300
    }


    @IBAction func cancel(_ sender: Any) {
        navigationController?.dismiss(animated: true)
   }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }

    func readJsonEstados() {
        let url = Bundle.main.url(forResource: "EstadosECidades", withExtension: "json")!
        do {
            let data = try Data(contentsOf: url)
            let jsonResult = try JSONDecoder().decode(RootState.self, from: data)

            //handles the array of countries on your json file.
            self.estadosJSON = jsonResult.estado
            self.cidades = self.estadosJSON.first!.cidades

        } catch {
            let alerta = Alerta(titulo: "Erro ao Carregar", mensagem: "Erro ao carregar Estados e Cidades. Por favor reinicie o app")
            self.present(alerta.getAlerta(), animated: true, completion: nil)
        }
    }

    func readJsonEspecialidades() {
        let url = Bundle.main.url(forResource: "Especialidades", withExtension: "json")!
        do {
            let data = try Data(contentsOf: url)
            let jsonResult = try JSONDecoder().decode(RootEsp.self, from: data)

            //handles the array of specialties on your json file.
            self.especialidadesJSON = jsonResult.especialidade
            self.especialidades2 = self.especialidadesJSON.first!.especialidade2
        } catch {
            let alerta = Alerta(titulo: "Erro ao Carregar", mensagem: "Erro ao carregar Especialidades. Por favor reinicie o app")
            self.present(alerta.getAlerta(), animated: true, completion: nil)
        }
    }

    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destination.
     // Pass the selected object to the new view controller.
     }
     */

}
class Alert {
    class func show(titulo: String, mensagem: String, vc: UIViewController) {
        let alerta = UIAlertController(title: titulo, message: mensagem, preferredStyle: .alert)
        let acaoCancelar = UIAlertAction(title: "Ok", style: .cancel, handler: nil)

        alerta.addAction(acaoCancelar)

        //if more than one VC is presenting, or the same one is presenting twice, this might at least tell you which one (assuming it has a title) or when (if the same one is presenting twice)
        print("\(vc.title) is presenting alert")

        vc.present(alerta, animated: true)
    }
}

class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Alert.show(titulo: "title", mensagem: "this is an alert", vc: self)
    }
}
extension UIViewController {
func showAlert(titulo: String, mensagem: String, vc: UIViewController) {
        let alerta = UIAlertController(title: titulo, message: mensagem, preferredStyle: .alert)
        let acaoCancelar = UIAlertAction(title: "Ok", style: .cancel, handler: nil)

        alerta.addAction(acaoCancelar)

        //if more than one VC is presenting, or the same one is presenting twice, this might at least tell you which one (assuming it has a title) or when (if the same one is presenting twice)
        print("\(vc.title) is presenting alert")

        vc.present(alerta, animated: true)
}}
showAlert(titulo: "YourTitle", mensagem: "YourMessage", vc: self)
import UIKit

class ViewController: UIViewController {

let button = UIButton(type: .system)

override func viewDidLoad() {
    super.viewDidLoad()
    button.backgroundColor = .black
    button.setTitle("Alert", for: .normal)
    button.setTitleColor(.white, for: .normal)
    button.addTarget(self, action: #selector(handleAlert), for: .touchUpInside)
    button.translatesAutoresizingMaskIntoConstraints = false

    view.addSubview(button)
    button.heightAnchor.constraint(equalToConstant: 50).isActive = true
    button.widthAnchor.constraint(equalToConstant: 100).isActive = true
    button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    // Do any additional setup after loading the view.
}

@objc fileprivate func handleAlert() {
    OperationQueue.main.addOperation {
        showAlert(titulo: "YourTilte", mensagem: "YourMessage", vc: self)
         print("On main thread: \(Thread.current.isMainThread)")
    }
}

extension UIViewController {
func showAlert(titulo: String, mensagem: String, vc: UIViewController) {
    let alerta = UIAlertController(title: titulo, message: mensagem, preferredStyle: .alert)
    let acaoCancelar = UIAlertAction(title: "Ok", style: .cancel, handler: nil)

    alerta.addAction(acaoCancelar)
    vc.present(alerta, animated: true)
 }
}