我的问题是我有两个viewControllers连接模态segue像普通A ---> B,A有像textFields,开关,按钮和mapView的控件,我得到userLocation.B目前只有一个按钮和一个mapView,但是当我点击退出按钮时,它确实成功解除了viewController B并显示A只有控件被冻结,不能再点击任何东西,我不知道为什么.有帮助吗?
B代码
import UIKit import MapKit import Parse import CoreLocation class MapaMososViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate { @IBOutlet weak var mapMozosFollow: MKMapView! var totlaAutomozo: String! var fechaRegistro: String! override func viewDidLoad() { super.viewDidLoad() mapMozosFollow.delegate = self mapMozosFollow.showsUserLocation = true mapMozosFollow.showsTraffic = false mapMozosFollow.showsScale = false print(mapMozosFollow.userLocation.location) } override func viewDidAppear(_ animated: Bool) { self.displayError(error: "Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totlaAutomozo!) la fecha registrada \(fechaRegistro!)") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func viewWillDisappear(_ animated: Bool) { } @IBAction func salirTapped(_ sender: UIButton) { self.dismiss(animated: true, completion: { print("here dismissing") }) } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { print(locations.last!.coordinate) centerMapOnLocation(locations.last!) } let regionRadius: CLLocationDistance = 2000 func centerMapOnLocation(_ location: CLLocation) { let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0) mapMozosFollow.setRegion(coordinateRegion, animated: true) } }
编辑1:ViewController代码.
import UIKit import Parse import MapKit import BraintreeDropIn import Braintree class ViewController: UIViewController, PayPalPaymentDelegate, PayPalFuturePaymentDelegate, PayPalProfileSharingDelegate, CLLocationManagerDelegate, UITextFieldDelegate, MKMapViewDelegate, BTDropInViewControllerDelegate { @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var mapaLugar: MKMapView! @IBOutlet weak var numeroExteriorTextField: UITextField! @IBOutlet weak var telefonoTextField: UITextField! @IBOutlet weak var lavadoSwitch: UISwitch! @IBOutlet weak var lavadoYAspiradSwitch: UISwitch! @IBOutlet weak var numeroCarrosTextField: UITextField! @IBOutlet weak var numeroMinivanTextField: UITextField! @IBOutlet weak var numeroPickUpsTextField: UITextField! @IBOutlet weak var numeroVansTextField: UITextField! @IBOutlet weak var numeroAspiradoCarrosTextField: UITextField! @IBOutlet weak var numeroAspiradoMinivanTextField: UITextField! @IBOutlet weak var numeroAspiradoPickUpsTextField: UITextField! @IBOutlet weak var numeroAspiradoVansTextField: UITextField! @IBOutlet weak var botonRealizarPedido: UIButton! @IBOutlet weak var botonInstrucciones: UIButton! @IBOutlet weak var totalLabel: UILabel! var showAlertFirstTime: Bool = true var locationManager: CLLocationManager = CLLocationManager() var ubicacion: CLLocationCoordinate2D! var environment:String = PayPalEnvironmentSandbox { willSet(newEnvironment) { if (newEnvironment != environment) { PayPalMobile.preconnect(withEnvironment: newEnvironment) } } } var braintreeClient: BTAPIClient? let defaults = UserDefaults.standard var resultText = "" // empty var payPalConfig = PayPalConfiguration() // default var total: NSDecimalNumber! var vistaDeMozos: Bool = false var fechaRegistro: String! var totalToSend: String! @IBOutlet weak var constrainSizeMap: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() botonInstrucciones.backgroundColor = UIColor(colorLiteralRed: (200.0/255.0), green: 0.0, blue: 0.0, alpha: 1.0) botonInstrucciones.layer.cornerRadius = 3 botonInstrucciones.layer.borderWidth = 2 botonInstrucciones.layer.borderColor = UIColor.clear.cgColor botonInstrucciones.layer.shadowColor = UIColor(colorLiteralRed: (100.0/255.0), green: 0.0, blue: 0.0, alpha: 1.0).cgColor botonInstrucciones.layer.shadowOpacity = 1.0 botonInstrucciones.layer.shadowRadius = 1.0 botonInstrucciones.layer.shadowOffset = CGSize(width: 0, height: 3) self.locationManager.requestWhenInUseAuthorization() self.locationManager.requestAlwaysAuthorization() self.locationManager.startUpdatingLocation() NotificationCenter.default.post(name: Notification.Name(rawValue: "keyPressed"), object: nil) numeroCarrosTextField.delegate = self numeroMinivanTextField.delegate = self numeroPickUpsTextField.delegate = self numeroVansTextField.delegate = self numeroAspiradoCarrosTextField.delegate = self numeroAspiradoMinivanTextField.delegate = self numeroAspiradoPickUpsTextField.delegate = self numeroAspiradoVansTextField.delegate = self do { if defaults.object(forKey: "clientId") == nil || clientId == "000" { let idTest = try PFCloud.callFunction("newCutomer", withParameters: nil) print(idTest) clientId = idTest as! String defaults.set(clientId, forKey: "clientId") } else { print(self.clientId) } } catch let error { print(error) } if defaults.object(forKey: "clientId") == nil { } else { clientId = defaults.string(forKey: "clientId")! print(clientId) } fetchClientToken() NotificationCenter.default.addObserver( self, selector: #selector(ViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil ) NotificationCenter.default.addObserver( self, selector: #selector(ViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil ) scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.interactive let touch = UITapGestureRecognizer(target: self, action: #selector(ViewController.singleTapGestureCaptured(gesture:))) scrollView.addGestureRecognizer(touch) } func singleTapGestureCaptured(gesture: UITapGestureRecognizer){ self.view.endEditing(true) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if showAlertFirstTime { showAlertFirstTime = false } else { } } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) PayPalMobile.preconnect(withEnvironment: environment) print("stop test") } @IBAction func realizarPedidoTapped(_ sender: UIButton) { let numeroExterior = numeroExteriorTextField.text! let numeroMotosLavado = numeroCarrosTextField.text! let numeroDeportivosLavado = numeroMinivanTextField.text! let numeroCarroLavado = numeroPickUpsTextField.text! let numeroCamionLavado = numeroVansTextField.text! let numeroMotoLavadoAspirado = numeroAspiradoCarrosTextField.text! let numeroDeportivoLavadoAspirado = numeroAspiradoMinivanTextField.text! let numeroCarroLavadoAspirado = numeroAspiradoPickUpsTextField.text! let numeroCamionLavadoAspirado = numeroAspiradoVansTextField.text! let numeroTelefono = telefonoTextField.text! if numeroExterior == "" || numeroTelefono == "" { displayError("Error", message: "Te falto llenar tu numero exterior y/o telefono") } else { //Braintree init self.braintreeClient = BTAPIClient(authorization: clientToken) let items = [item1] let subtotal = PayPalItem.totalPrice(forItems: items) //var subtotal = PayPalItem.totalPrice(forItems: items) let shipping = NSDecimalNumber(string: "0.00") let tax = NSDecimalNumber(string: "0.00") //details ??? let paymentDetails = PayPalPaymentDetails(subtotal: subtotal, withShipping: shipping, withTax: tax) self.total = subtotal.adding(shipping).adding(tax) let payment = PayPalPayment(amount: total, currencyCode: "MXN", shortDescription: "Automozo inc", intent: .sale) payment.items = items payment.paymentDetails = paymentDetails print("\(payment.localizedAmountForDisplay)") self.showDropIn(clientTokenOrTokenizationKey: clientToken) if (payment.processable) { let paymentViewController = PayPalPaymentViewController(payment: payment, configuration: payPalConfig, delegate: self) } else { print("Payment not processalbe: \(payment.description)") print("payment not processable \(payment)") displayError("Error", message: "Hubo un error al procesar tu pago, por favor intenta de nuevo.") } } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { super.prepare(for: segue, sender: sender) if segue.identifier == "MapaMozosSegue" { let mapaMozosVC = segue.destination as! MapaMososViewController mapaMozosVC.totlaAutomozo = totalToSend! mapaMozosVC.fechaRegistro = fechaRegistro locationManager.stopUpdatingLocation() } } func textFieldDidEndEditing(_ textField: UITextField) { textField.resignFirstResponder() print("test text field ended") if textField.text == "" { textField.text = "0" } var numeroCarrosLavadoVar = numeroCarrosTextField.text! var numeroMinivansLavadoVar = numeroMinivanTextField.text! var numeroPickUpsLavadoVar = numeroPickUpsTextField.text! var numeroVansLavadoVar = numeroVansTextField.text! var numeroCarrosLavadoAspiradoVar = numeroAspiradoCarrosTextField.text! var numeroMinivansLavadoAspiradoVar = numeroAspiradoMinivanTextField.text! var numeroPickUpsLavadoAspiradoVar = numeroAspiradoPickUpsTextField.text! var numeroVansLavadoAspiradoVar = numeroAspiradoVansTextField.text! if numeroCarrosLavadoVar == "" { numeroCarrosLavadoVar = "0" numeroCarrosTextField.text = "0" } if numeroMinivansLavadoVar == "" { numeroMinivansLavadoVar = "0" numeroMinivanTextField.text = "0" } if numeroPickUpsLavadoVar == "" { numeroPickUpsLavadoVar = "0" numeroPickUpsTextField.text = "0" } if numeroVansLavadoVar == "" { numeroVansLavadoVar = "0" numeroVansTextField.text = "0" } if numeroCarrosLavadoAspiradoVar == "" { numeroCarrosLavadoAspiradoVar = "0" numeroAspiradoCarrosTextField.text = "0" } if numeroMinivansLavadoAspiradoVar == "" { numeroMinivansLavadoAspiradoVar = "0" numeroMinivanTextField.text = "0" } if numeroPickUpsLavadoAspiradoVar == "" { numeroPickUpsLavadoAspiradoVar = "0" numeroAspiradoPickUpsTextField.text = "0" } if numeroVansLavadoAspiradoVar == "" { numeroVansLavadoAspiradoVar = "0" numeroVansTextField.text = "0" } let priceOfLavadoCarro = Int(numeroCarrosLavadoVar)! * pricesLavado["LavadoCarro"]! let priceOfLavadoMinivan = Int(numeroMinivansLavadoVar)! * pricesLavado["LavadoMinivan"]! let priceOfLavadoPickUp = Int(numeroPickUpsLavadoVar)! * pricesLavado["LavadoPickUp"]! let priceOfLavadoVan = Int(numeroVansLavadoVar)! * pricesLavado["LavadoVan"]! //Lavado y Aspirado let priceOfLavadoYAspiradoCarro = Int(numeroCarrosLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoCarro"]! let priceOfLavadoYAspiradoMinivan = Int(numeroMinivansLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoMinivan"]! let priceOfLavadoYAspiradoPickUp = Int(numeroPickUpsLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoPickUp"]! let priceOfLavadoYAspiradoVan = Int(numeroVansLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoVan"]! let totalAutomozo = priceOfLavadoCarro + priceOfLavadoMinivan + priceOfLavadoPickUp + priceOfLavadoVan + priceOfLavadoYAspiradoCarro + priceOfLavadoYAspiradoMinivan + priceOfLavadoYAspiradoPickUp + priceOfLavadoYAspiradoVan print(totalAutomozo) totalLabel.text = "\(totalAutomozo).00" textField.resignFirstResponder() } func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { if (textField.text?.characters.count)! == 1 { print("text quota meet") textField.resignFirstResponder() self.view.endEditing(true) return true } else { textField.text = "0" } return true } let regionRadius: CLLocationDistance = 100 func centerMapOnLocation(_ location: CLLocation) { let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0) mapaLugar.setRegion(coordinateRegion, animated: true) } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { centerMapOnLocation(locations.last!) ubicacion = locations.last!.coordinate } // Mark - Braintree methods func showDropIn(clientTokenOrTokenizationKey: String) { var value: Bool = false var totlaAutomozo = self.totalLabel.text let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MMM dd YYYY HH:mm" dateFormatter.timeZone = NSTimeZone.local fechaRegistro = dateFormatter.string(from: Date()) let request = BTDropInRequest() request.amount = "\(total)" request.currencyCode = "MXN" print(request.description) BTUIKAppearance.darkTheme() BTUIKAppearance.sharedInstance().activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray // request. let dropIn = BTDropInController(authorization: clientTokenOrTokenizationKey, request: request) { (controller, result, error) in if (error != nil) { print("ERROR") } else if (result?.isCancelled == true) { print("CANCELLED") } else if let result = result { // Use the BTDropInResult properties to update your UI print(result.paymentOptionType) print("payment method: \(result.paymentMethod?.nonce)") print("ppayment desc \(result.paymentDescription)") print(result.paymentIcon.description) value = self.postNonceToServer(paymentMethodNonce: (result.paymentMethod?.nonce)!) } controller.dismiss(animated: true, completion: nil) if value { self.locationManager.stopUpdatingLocation() self.performSegue(withIdentifier: "MapaMozosSegue", sender: self) self.vistaDeMozos = true } else { self.displayError("Alerta", message: "El pedido ha sido cancelado exitosamente.") //top row self.numeroCarrosTextField.text = "0" self.numeroMinivanTextField.text = "0" self.numeroPickUpsTextField.text = "0" self.numeroVansTextField.text = "0" //bottom row self.numeroAspiradoCarrosTextField.text = "0" self.numeroAspiradoMinivanTextField.text = "0" self.numeroAspiradoPickUpsTextField.text = "0" self.numeroAspiradoVansTextField.text = "0" //data self.telefonoTextField.text = "" self.telefonoTextField.text = "" } } self.present(dropIn!, animated: true, completion: nil) } func userDidCancelPayment() { self.dismiss(animated: true, completion: nil) } func postNonceToServer(paymentMethodNonce: String) -> Bool { var val = true do { var response = try PFCloud.callFunction("checkout", withParameters: ["payment_method_nonce":paymentMethodNonce, "amount":"\(total!).00", "customerId": clientId]) print(response) } catch let error { print(error.localizedDescription) } let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MMM. dd, YYYY HH:mm" dateFormatter.timeZone = NSTimeZone.local fechaRegistro = dateFormatter.string(from: Date()) let usuarioPagado: PFObject = PFObject(className: "Ordenes") let location: PFGeoPoint = PFGeoPoint(latitude: ubicacion.latitude, longitude: ubicacion.longitude) usuarioPagado["Ubicacion"] = location usuarioPagado["NumeroExterior"] = numeroExteriorTextField.text! usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text! usuarioPagado["LavadoCarro"] = numeroCarrosTextField.text! usuarioPagado["LavadoMiniVan"] = numeroMinivanTextField.text! usuarioPagado["LavadoPickUp"] = numeroPickUpsTextField.text! usuarioPagado["LavadoDeVan"] = numeroVansTextField.text! usuarioPagado["LavadoAspiradoCarro"] = numeroAspiradoCarrosTextField.text! usuarioPagado["LavadoAspiradoMiniVan"] = numeroAspiradoMinivanTextField.text! usuarioPagado["LavadoAspiradoPickUp"] = numeroAspiradoPickUpsTextField.text! usuarioPagado["LavadoAspiradoDeVan"] = numeroAspiradoVansTextField.text! usuarioPagado["Monto"] = totalLabel.text! usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text! usuarioPagado["TipoDeCelular"] = "iPhone" usuarioPagado["FechaDeOrden"] = fechaRegistro self.totalToSend = self.totalLabel.text! usuarioPagado.saveInBackground() { (success: Bool, error: Error?) -> Void in if error == nil { //done print("saved object") val = false } else { //not done print("not saved because \(error?.localizedDescription)") } } numeroCarrosTextField.text = "0" numeroMinivanTextField.text = "0" numeroPickUpsTextField.text = "0" numeroVansTextField.text = "0" numeroAspiradoCarrosTextField.text = "0" numeroAspiradoMinivanTextField.text = "0" numeroAspiradoPickUpsTextField.text = "0" numeroAspiradoVansTextField.text = "0" totalLabel.text = "00.00" self.lavadoSwitch.isOn = false self.lavadoYAspiradSwitch.isOn = false self.numeroExteriorTextField.text = "" self.telefonoTextField.text = "" self.numeroCarrosTextField.isHidden = true self.numeroMinivanTextField.isHidden = true self.numeroPickUpsTextField.isHidden = true self.numeroVansTextField.isHidden = true self.numeroAspiradoCarrosTextField.isHidden = true self.numeroAspiradoMinivanTextField.isHidden = true self.numeroAspiradoPickUpsTextField.isHidden = true self.numeroAspiradoVansTextField.isHidden = true return val } func drop(inViewControllerDidLoad viewController: BTDropInViewController) { print("did load view drop") } func drop(inViewControllerDidCancel viewController: BTDropInViewController) { print("did cancel drop payment") } func drop(inViewControllerWillComplete viewController: BTDropInViewController) { print("drop will complete payment") } func drop(_ viewController: BTDropInViewController, didSucceedWithTokenization paymentMethodNonce: BTPaymentMethodNonce) { var totlaAutomozo = totalLabel.text let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MMM dd YYYY HH:mm" dateFormatter.timeZone = NSTimeZone.local fechaRegistro = dateFormatter.string(from: Date()) print("did succeeded with tokenization") print(" \(paymentMethodNonce.nonce)") var value = postNonceToServer(paymentMethodNonce: paymentMethodNonce.nonce) self.dismiss(animated: true, completion: nil) if value { displayError("Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totlaAutomozo ?? "00.00") la fecha registrada \(fechaRegistro)") } else { self.displayError("Error", message: "Hubo un error al guardar tu informacion, ponte en contacto con nosotros.") } } func fetchClientToken() { do { let response = try PFCloud.callFunction("generateToken", withParameters: ["clientId": clientId]) self.clientToken = response as! String } catch let error { print(error) } } func keyboardWillShow(notification:NSNotification){ var userInfo = notification.userInfo! var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue keyboardFrame = self.view.convert(keyboardFrame, from: nil) var contentInset:UIEdgeInsets = self.scrollView.contentInset contentInset.bottom = keyboardFrame.size.height self.scrollView.contentInset = contentInset } func keyboardWillHide(notification:NSNotification){ let contentInset:UIEdgeInsets = UIEdgeInsets.zero self.scrollView.contentInset = contentInset } func scrollViewDidScroll(_ scrollView: UIScrollView) { self.view.endEditing(true) } func showFullMap() { if vistaDeMozos { self.telefonoTextField.isHidden = true self.botonRealizarPedido.isHidden = true self.lavadoSwitch.isHidden = true self.lavadoYAspiradSwitch.isHidden = true self.botonRealizarPedido.isHidden = true self.numeroExteriorTextField.isHidden = true self.numeroCarrosTextField.isHidden = true self.numeroMinivanTextField.isHidden = true self.numeroPickUpsTextField.isHidden = true self.numeroVansTextField.isHidden = true self.numeroAspiradoCarrosTextField.isHidden = true self.numeroAspiradoMinivanTextField.isHidden = true self.numeroAspiradoPickUpsTextField.isHidden = true self.numeroAspiradoVansTextField.isHidden = true self.view.layoutSubviews() } else { } } }
nils.. 17
您是否尝试将应用程序与调试器暂停以检查堆栈帧?有时,这可以帮助您发现死锁或无限循环.您可以在代码编辑器和调试器之间的栏中找到暂停按钮(如果隐藏调试器,则在底部):
查看Xcode窗口左侧Debug Navigator中的堆栈帧.你能看到任何可疑的东西吗?这是一个堆栈框架,指示应用程序在主运行循环中空闲:
当应用程序等待用户输入时,这通常是完全正常的.如果您看到以下内容,则可能会遇到死锁:
信号量停止线程继续,直到某个其他线程再次打开信号量.如果两个或多个线程停止等待,则处理死锁.如果涉及主线程,则应用程序将被冻结.
我能想到的第三种可能性是主线程上的无限循环:
当然这个很容易发现:)堆栈帧中较暗的条目来自您自己的代码.您可以单击这些条目以查找确切位置,并使用调试器检查变量.其他条目将显示汇编.
如果你通过暂停调试器找不到任何可疑的东西,我会开始逐位删除那些代码部分,每次尝试重现问题.有两种可能的结果:
你删除了一些无害的代码,突然它按预期工作.然后,您可以仔细查看已删除的代码,从而更轻松地解决问题.
您最终会得到一个展示该问题的最小项目.现在这更容易调试和推理,因为没有其他任何东西可以分散你的注意力.当您的代码示例尽可能小时,您也有更高的可能性从同事那里获得帮助,或者在Stack Overflow上获得帮助.
第三个攻击向量是检查View Debugger:
冻结视图控制器上方是否有阻止用户事件的透明视图?
是否在所涉及的控件和视图上启用了用户交互?选择一个视图并选中右侧的Object Inspector:
您是否尝试将应用程序与调试器暂停以检查堆栈帧?有时,这可以帮助您发现死锁或无限循环.您可以在代码编辑器和调试器之间的栏中找到暂停按钮(如果隐藏调试器,则在底部):
查看Xcode窗口左侧Debug Navigator中的堆栈帧.你能看到任何可疑的东西吗?这是一个堆栈框架,指示应用程序在主运行循环中空闲:
当应用程序等待用户输入时,这通常是完全正常的.如果您看到以下内容,则可能会遇到死锁:
信号量停止线程继续,直到某个其他线程再次打开信号量.如果两个或多个线程停止等待,则处理死锁.如果涉及主线程,则应用程序将被冻结.
我能想到的第三种可能性是主线程上的无限循环:
当然这个很容易发现:)堆栈帧中较暗的条目来自您自己的代码.您可以单击这些条目以查找确切位置,并使用调试器检查变量.其他条目将显示汇编.
如果你通过暂停调试器找不到任何可疑的东西,我会开始逐位删除那些代码部分,每次尝试重现问题.有两种可能的结果:
你删除了一些无害的代码,突然它按预期工作.然后,您可以仔细查看已删除的代码,从而更轻松地解决问题.
您最终会得到一个展示该问题的最小项目.现在这更容易调试和推理,因为没有其他任何东西可以分散你的注意力.当您的代码示例尽可能小时,您也有更高的可能性从同事那里获得帮助,或者在Stack Overflow上获得帮助.
第三个攻击向量是检查View Debugger:
冻结视图控制器上方是否有阻止用户事件的透明视图?
是否在所涉及的控件和视图上启用了用户交互?选择一个视图并选中右侧的Object Inspector: