iOS 应用程序在 swift 中关闭视图后冻结
Posted
技术标签:
【中文标题】iOS 应用程序在 swift 中关闭视图后冻结【英文标题】:iOS app freezes after dismiss view in swift 【发布时间】:2017-01-26 00:15:20 【问题描述】:我的问题是,我有两个 viewControllers 与普通 A--->B 一样的模态 segue 连接,A 具有文本字段、开关、按钮和 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
【问题讨论】:
检查你的 deinit 方法是否被调用,并且你的 viewcontroller 在你第一次关闭时被成功释放。 deinit // 在这里检查 如果有,那么问题可能出在你的 A 视图控制器上,没有贴出来。 在“B代码”中不要忘记调用viewDidAppear中的超级实现,viewWillDisappear。也许它也可以解决您的问题。 可能相关:***.com/q/39608231 【参考方案1】:您是否尝试使用调试器暂停应用程序以检查堆栈帧?有时这可以帮助您发现死锁或无限循环。您会在代码编辑器和调试器之间的栏中找到暂停按钮(如果调试器被隐藏,则在底部):
在 Xcode 窗口左侧的 Debug Navigator 中查看堆栈帧。你能看出什么可疑的吗?这是一个堆栈帧,表明应用程序在主运行循环中处于空闲状态:
这通常是完全正常的,因为应用正在等待用户输入。如果您看到类似以下内容,您可能正在处理死锁:
信号量会阻止线程继续运行,直到其他线程再次打开信号量。如果两个或多个线程停止等待对方,您正在处理死锁。如果涉及主线程,应用程序将被冻结。
我能想到的第三种可能是主线程上的无限循环:
当然,这个很容易发现 :) 堆栈帧中较暗的条目来自您自己的代码。您可以单击这些条目以查找确切位置并使用调试器检查变量。其他条目将向您展示程序集。
如果您通过暂停调试器没有发现任何可疑之处,我将开始一点一点地删除这些代码部分,并尝试每次都重现问题。有两种可能的结果:
您删除了一些看起来无害的代码,然后它突然按预期工作了。然后,您可以仔细查看您删除的代码,从而更容易找出问题所在。
您最终会得到一个显示该问题的最小项目。这现在更容易调试和推理,因为没有其他东西会分散您对问题的注意力。当您的代码示例尽可能小时,您从同事或 Stack Overflow 获得帮助的可能性也更高。
第三个攻击向量正在检查 View Debugger:
冻结的视图控制器上方是否有任何透明视图阻止用户事件?
是否在涉及的控件和视图上启用了用户交互?选择一个视图并检查右侧的 Object Inspector:
【讨论】:
是的,我有一个死锁,我可以看到 semaphore_wait_trap() 有没有办法知道我从哪里得到它? 检查您是否看到任何有助于其他正在运行的线程的内容。看看你是否可以从阻塞线程的跟踪中推断出任何信息。这可能是一项艰巨的侦探工作。如果没有任何帮助,请按照我的建议将项目减少到最低限度并发布另一个问题。 我会先在A
中注释掉viewWillAppear
,但这只是一种预感......【参考方案2】:
尝试删除DispatchQueue.main.async
否则A viewController 将不会收到通知。它的交互已被禁用,因为 segue
//DispatchQueue.main.async
self.dismiss(animated: true, completion:
print("here dismissing")
)
//
【讨论】:
完成我已更改为 ti 没有帮助,我看到发生了一些奇怪的事情。解除 VC B 后,它返回 A 去 self.dismiss(animated: true, completion: print("heredismissing") ) 这样做并返回 B 完成怎么来?【参考方案3】:确保检查是否有任何 NSDelayedPerforming 方法阻塞了主线程(Foundation > NSRunloop)。即 performSelector afterDelay...
就我而言(Objective-C),我必须在 ViewController 的 viewDidDisappear 实例方法中使用 cancelPreviousPerformRequestsWithTarget。
[NSObject cancelPreviousPerformRequestsWithTarget:self];
我认为这同样适用于使用 NSTimer.scheduledTimerWithTimeInterval (Swift) 而不会在正确的生命周期方法中使计时器失效。
【讨论】:
以上是关于iOS 应用程序在 swift 中关闭视图后冻结的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中关闭键盘时,UIToolbar 不再显示在视图中