我在项目中传递了展开数据的问题。 正如我在dfri中看到的那样在这篇文章中回答Passing data with unwind segue 它工作得很好,我打印的变量保持它们以正确的顺序打印的值,第一个是传递的变量,第二个是传递的变量。第二次从展开功能打印。 当我以与上述示例相同的方式实现展开功能时,我得到完全不同的顺序o变量打印。 在我的例子中,我首先从unwind函数获得打印,然后从CollectionView didSelect函数获得打印。 并且应该接收数据的变量保持为零。 我还尝试将值赋给静态var并使用它但不改变它。 这是两个ViewControllers代码:
import UIKit import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var dropPinButton: UIButton!
@IBOutlet weak var centerMApButton: UIButton!
var pin: AnnotationPinn!
var dataReceived: String?
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
// variables that hold values for selected icon, to be used for displaying the pin
let latitude: Double = 44.498955
let longitude: Double = 11.327591
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let region = MKCoordinateRegionMakeWithDistance(coordinate, 1000, 1000)
mapView.setRegion(region, animated: true)
// title may be to be taken from iconNames[indexpath.row]
pin = AnnotationPinn(title: "strada chiusa", subtitle: "", coordinate: coordinate)
}
//custom pin image , named: iconsImages[indexPath.row]
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKAnnotationView(annotation: pin, reuseIdentifier: "strada chiusa")
annotationView.image = UIImage(named: "\(String(describing: dataReceived))") // here choose the image to load // annotationView.image = UIImage(named: "\(String(describing: MyVariables.dataReceived))") // here choose the image to load
// annotationView.image = UIImage(iconsNames[1])
let transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
annotationView.transform = transform
return annotationView
}
func dropPin() { // print("3\(String(describing: dataReceived))")
mapView.addAnnotation(pin)
}
@IBAction func dropPinButton(_ sender: Any) {
performSegue(withIdentifier: "chooseIconSegue", sender: self)
}
@IBAction func unwindHere(sender:UIStoryboardSegue) { // datas coming back
if let sourceViewController = sender.source as? IconsViewController { // MyVariables.dataReceived = sourceViewController.dataPassed
dataReceived = sourceViewController.dataPassed // print(MyVariables.dataReceived!)
print("3\(String(describing: dataReceived))")
dropPin()
}
}
}
VC2
import UIKit
class IconsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var dataPassed: String?
@IBOutlet weak var iconsCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
var iconsNames = ["lavori in corso", "ciclabile chiusa", "strada chiusa", "bici rubata", "bici sospetta" ]
var iconsImages = [UIImage(named: "lavori in corso"), UIImage(named: "ciclabile chiusa"), UIImage(named: "strada chiusa"), UIImage(named: "bici rubata"), UIImage(named: "bici sospetta")]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return iconsNames.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "iconCell", for: indexPath as IndexPath) as! IconsCollectionViewCell
cell.iconImage?.image = self.iconsImages[indexPath.row]
cell.iconLabel?.text = iconsNames[indexPath.row]
// MyVariables.dataReceived = iconsNames[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
dataPassed = iconsNames[indexPath.row]
MyVariables.dataReceived = dataPassed
print ("2\(iconsNames[indexPath.row])")
print("1\(dataPassed!)")
// navigationController?.popViewController(animated: true) // // dismiss(animated: true, completion: nil)
}
}
答案 0 :(得分:1)
正如您所发现的,当您直接从collectionView单元格中连接segue时,segue会在didSelectItemAt
运行之前运行。
有几种方法可以解决这个问题。一种是跳过使用didSelectItemAt
并在prepare(for:sender)
中完成所有工作。
在这种情况下,sender
是collectionView单元格,因此使用它来获取indexPath
,然后设置数据:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let cell = sender as? UICollectionViewCell,
let indexPath = self.iconsCollectionView.indexPath(for: cell) {
self.dataPassed = iconsNames[indexPath.row]
}
}
注意:您应该为您的展开segue提供一个标识符(例如"unwindToCaller"
)并检查它。您可以在文档大纲视图中找到segue,并在Xcode右侧的 Attributes Inspector 中设置标识符。
然后你会这样检查:
if segue.identifier == "unwindToCaller" {
if let cell = sender as? ...
}
替代解决方案:
"returnToCaller"
。在didSelectItemAt
中,在设置数据值后调用segue:
self.performSegue(withIdentifier: "returnToCaller", sender: self)