ios - 解除意外行为

标签 ios swift unwind-segue

我的项目中传递展开数据时遇到问题。 正如我在这篇文章的 dfri 回答中看到的 Passing data with unwind segue 它工作得很好,我打印了保存值的变量,它们以正确的顺序打印,第一个是要传递的变量,第二个是传递的变量。第二次从展开功能中打印出来。 当我以与上述示例相同的方式实现展开功能时,我得到了完全不同的变量打印顺序。 在我的例子中,我首先从 unwind 函数获得打印,然后从 CollectionView didSelect 函数获得打印。 并且应该接收数据的变量保持为零。 我还尝试为静态变量赋值并使用它,但也没有对其进行任何更改。 这是两个 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)

}
}

最佳答案

正如您所发现的,当您直接从 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]
    }
}

注意:您应该为展开的转场提供一个标识符(例如 "unwindToCaller")并检查它。您可以在 Document Outline View 中找到 segue,并在 Xcode 右侧的 Attributes Inspector 中设置标识符。

然后你会这样检查:

if segue.identifier == "unwindToCaller" {
    if let cell = sender as? ...

}

替代解决方案:

  1. 不是从 collectionView 单元连接你的 segue,而是从 collectionViewController 顶部的 viewController 图标连接它。为 segue 提供一个标识符,例如 "returnToCaller"
  2. didSelectItemAt 中,设置数据值后调用 segue:

    self.performSegue(withIdentifier: "returnToCaller", sender: self)
    

关于ios - 解除意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49797566/

相关文章:

ios - 禁用 UIPageViewController 弹跳 - Swift

ios - 如何在 Swift 3 的 Table Cell 中设置多行 UILabel?

swift - Root View Controller 和展开 segues?

ios - 在主 Controller 部分加载 uiviewcontroller

ios - 在模态视图 Controller 后面更改 View Controller

ios - 从第二个 View Controller 到第一个 View Controller ios8

android - 将 OnClick 翻译成 OnTouch(或类似的东西)?

ios - 设置 UIScrollView 可见区域

ios - 检索核心数据实体中的最后一行/对象作为字符串

ios - 如何在 UIBarButtonItem 中制作一个箭头,就像快速的后退按钮箭头一样