我收到一条警告:“警告:尝试显示不在窗口层次结构中的视图!”
我认为我有一个与通过 segue 呈现新视图控制器相关的逻辑问题。我正在尝试对位置进行地理编码并将坐标分配给结构中的变量(以及几个其他变量),然后我将其发送到一个新的控制器,该控制器在 mapView 上显示一个图钉。
通过断点和打印语句,似乎我的 prepareForSegue 函数被调用了两次,一次是在地理位置实际发生之前,一次是在调用下一个视图控制器之后,一次是在地理位置完成之后......但我相信它无法显示地理编码的位置,因为视图控制器已经存在......我总是在海洋中间的某个地方结束。
我已经尝试移动我的异步函数(performUIUpdatesOnMain)并将我的地图和注释显示功能移动到第二个视图控制器中的 viewDidAppear 中,但是这些解决方案不起作用。我究竟做错了什么?
以下是每个视图控制器的相关部分:
第一个视图控制器:
@IBAction func findLocationPressed(_ sender: Any) {
// Show alert if locationTextField or websiteTextField are empty
if self.locationTextField.text == "" || self.websiteTextField.text == "" {
let alertController = UIAlertController()
let alert = UIAlertAction(title: "You didn't enter a location or website", style: .cancel, handler: nil)
alertController.addAction(alert)
present(alertController, animated: true, completion: nil)
} else {
// Populate locationData struct with locationText and mediaURL
locationData.locationText = self.locationTextField.text!
locationData.mediaURL = self.websiteTextField.text!
// Get the location
getLocation(completionHandler: { (success, error) in
//AlertView.activityIndicator
//performUIUpdatesOnMain {
// If geocoding successful...
if success {
// Present the ConfirmLocationViewController
self.performSegue(withIdentifier: "FinishSegue", sender: self)
/*let controller = self.storyboard?.instantiateViewController(withIdentifier: "ConfirmLocationViewController") as! ConfirmLocationViewController
self.present(controller, animated: true, completion: nil) */
} else {
let alertController = UIAlertController()
let alert = UIAlertAction(title: "Couldn't find that location", style: .cancel, handler: nil)
alertController.addAction(alert)
self.present(alertController, animated: true, completion: nil)
//}
}
})
}
}
func getLocation(completionHandler: @escaping (_ success: Bool, _ error: NSError?) -> Void) {
// Create an instance of the geocoder
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(locationTextField.text!) { (placemark, error) in
performUIUpdatesOnMain {
// Check for an error when retrieving the coordinates
if error != nil {
let userInfo = [NSLocalizedDescriptionKey: "There was an error attempting to retrieve your coordinates"]
completionHandler(false, NSError(domain: "getLocation", code: 0, userInfo: userInfo))
} else {
// GUARD: Confirm placemark exists
guard let placemark = placemark else {
let userInfo = [NSLocalizedDescriptionKey: "There was an error with your placemark"]
completionHandler(false, NSError(domain: "getLocation", code: 1, userInfo: userInfo))
return
}
// GUARD: Confirm latitude exists in placemark
guard let latitude = placemark[0].location?.coordinate.latitude else {
let userInfo = [NSLocalizedDescriptionKey: "There was an error with the latitude"]
completionHandler(false, NSError(domain: "getLocation", code: 2, userInfo: userInfo))
return
}
// GUARD: Confirm longitude exists in placemark
guard let longitude = placemark[0].location?.coordinate.longitude else {
let userInfo = [NSLocalizedDescriptionKey: "There was an error with the longitude"]
completionHandler(false, NSError(domain: "getLocation", code: 3, userInfo: userInfo))
return
}
// Populate locationData with latitude and longitude
self.locationData.latitude = latitude
self.locationData.longitude = longitude
completionHandler(true, nil)
print("getLocation was successful. \n Latitude=\(latitude) \n Longitude=\(longitude)")
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FinishSegue" {
let controller = segue.destination as! ConfirmLocationViewController
controller.locationData = self.locationData
print("This is the locationData being sent via prepareForSegue: \(locationData)")
}
}
第二个视图控制器:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
print("viewWillAppear in ConfirmLocationViewController has been called")
// Set the coordinates
let coordinates = CLLocationCoordinate2D(latitude: locationData.latitude, longitude: locationData.longitude)
print(coordinates)
// Set the map region
let region = MKCoordinateRegionMake(coordinates, MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
self.mapView.setRegion(region, animated: true)
self.mapView.delegate = self
// Set the annotation
let title = "\((User.shared.firstName) + " " + (User.shared.lastName))"
let subtitle = locationData.mediaURL
annotation.coordinate = coordinates
annotation.title = title
annotation.subtitle = subtitle
// Add the annotation
mapView.addAnnotation(self.annotation)
self.mapView.addAnnotation(self.annotation)
print("the current map region is: \(region)")
/*performUIUpdatesOnMain {
} */
}
我正在传递的名为 locationData 的结构包含四个变量:纬度、经度和两个字符串。
谢谢。